{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "using PyCall\n",
    "import SymPy: symbols, sympy, Sym\n",
    "using GAlgebra\n",
    "using Test"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PyObject <function signature at 0x000000002FE6DAE8>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "py\"\"\"\n",
    "def vector(ga, components):\n",
    "    basis = ga.mv()\n",
    "    return sum([components[i] * e for i, e in enumerate(basis)])\n",
    "\"\"\"\n",
    "const vector = py\"vector\"\n",
    "\n",
    "py\"\"\"\n",
    "def signature(ga):\n",
    "    basis = ga.mv()\n",
    "    signs = [e * e for e in basis]\n",
    "    p, q, r = 0, 0, 0\n",
    "    for sign in signs:\n",
    "        p += 1 if sign == 1 else 0\n",
    "        q += 1 if sign == -1 else 0\n",
    "        r += 1 if sign == 0 else 0\n",
    "\n",
    "    return (p, q, r)\n",
    "\"\"\"\n",
    "const signature = py\"signature\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PyObject <galgebra.ga.Ga object at 0x00000000313D8898>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Basic \n",
    "Hyper   = G(1)       # Hyperbolic numbers. \n",
    "ℂ       = G(0,1)     # Complex numbers.\n",
    "Dual    = G(0,0,1)   # Dual numbers.\n",
    "ℍ       = G(0,2)     # Quaternions.\n",
    "\n",
    "# Clifford\n",
    "Cl2       = G(2)     # Clifford algebra for 2D vector space.\n",
    "Cl3       = G(3)     # Clifford algebra for 3D vector space.\n",
    "Spacetime = G(1,3)   # Clifford algebra for timespace vectors.\n",
    "\n",
    "# Geometric\n",
    "PGA2D = G(2,0,1)     # Projective Euclidean 2D plane. (dual)\n",
    "PGA3D = G(3,0,1)     # Projective Euclidean 3D space. (dual)\n",
    "CGA2D = G(3,1)       # conformal 2D space. \n",
    "CGA3D = G(4,1)       # Conformal 3D space. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "test_geometric_product (generic function with 1 method)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function test_geometric_product(V)\n",
    "    dimV = range(0, stop=V.n)\n",
    "    I = V.I()\n",
    "\n",
    "    α = V.mv(\"α\", \"scalar\")\n",
    "    β = V.mv(\"β\", \"scalar\")\n",
    "    γ = V.mv(\"γ\", \"scalar\")\n",
    "    λ = V.mv(\"λ\", \"scalar\")\n",
    "\n",
    "    u = V.mv(\"u\", \"vector\")\n",
    "    v = V.mv(\"v\", \"vector\")\n",
    "    w = V.mv(\"w\", \"vector\")\n",
    "\n",
    "    A = V.mv(\"A\", \"mv\")\n",
    "    B = V.mv(\"B\", \"mv\")\n",
    "    C = V.mv(\"C\", \"mv\")\n",
    "    D = V.mv(\"D\", \"mv\")\n",
    "\n",
    "    R = V.mv(\"R\", \"spinor\")\n",
    "\n",
    "    return A*B #, V.mul_table_dict)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.143947 seconds (270.18 k allocations: 13.434 MiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{0} B^{0}\\right )  + \\left ( A B^{0} + A^{0} B\\right ) \\boldsymbol{e}_{0}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__0*B__0 + (A*B__0 + A__0*B)*e_0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(Hyper)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.002141 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}A B  + \\left ( A B^{0} + A^{0} B\\right ) \\boldsymbol{e}_{0}\\end{align*}"
      ],
      "text/plain": [
       "A*B + (A*B__0 + A__0*B)*e_0"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(Dual)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.002485 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B - A^{0} B^{0}\\right )  + \\left ( A B^{0} + A^{0} B\\right ) \\boldsymbol{e}_{0}\\end{align*}"
      ],
      "text/plain": [
       "A*B - A__0*B__0 + (A*B__0 + A__0*B)*e_0"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(ℂ)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.047692 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B - A^{1} B^{1} - A^{12} B^{12} - A^{2} B^{2}\\right )  + \\left ( A B^{1} + A^{1} B - A^{12} B^{2} + A^{2} B^{12}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} - A^{1} B^{12} + A^{12} B^{1} + A^{2} B\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B - A^{2} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\end{align*}"
      ],
      "text/plain": [
       "A*B - A__1*B__1 - A__12*B__12 - A__2*B__2 + (A*B__1 + A__1*B - A__12*B__2 + A__2*B__12)*e_1 + (A*B__2 - A__1*B__12 + A__12*B__1 + A__2*B)*e_2 + (A*B__12 + A__1*B__2 + A__12*B - A__2*B__1)*e_1^e_2"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(ℍ)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.012486 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} + A^{2} B^{2}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{2} B^{12}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{2} B\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B - A^{2} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 + A__2*B__2 + (A*B__1 + A__1*B + A__12*B__2 - A__2*B__12)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__2*B)*e_2 + (A*B__12 + A__1*B__2 + A__12*B - A__2*B__1)*e_1^e_2"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(Cl2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.138977 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} - A^{123} B^{123} - A^{13} B^{13} + A^{2} B^{2} - A^{23} B^{23} + A^{3} B^{3}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{123} B^{23} + A^{13} B^{3} - A^{2} B^{12} - A^{23} B^{123} - A^{3} B^{13}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{123} B^{13} + A^{13} B^{123} + A^{2} B + A^{23} B^{3} - A^{3} B^{23}\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} - A^{12} B^{123} - A^{123} B^{12} - A^{13} B^{1} + A^{2} B^{23} - A^{23} B^{2} + A^{3} B\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B + A^{123} B^{3} - A^{13} B^{23} - A^{2} B^{1} + A^{23} B^{13} + A^{3} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} + A^{12} B^{23} - A^{123} B^{2} + A^{13} B - A^{2} B^{123} - A^{23} B^{12} - A^{3} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} + A^{13} B^{12} + A^{2} B^{3} + A^{23} B - A^{3} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B - A^{13} B^{2} - A^{2} B^{13} + A^{23} B^{1} + A^{3} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 - A__123*B__123 - A__13*B__13 + A__2*B__2 - A__23*B__23 + A__3*B__3 + (A*B__1 + A__1*B + A__12*B__2 - A__123*B__23 + A__13*B__3 - A__2*B__12 - A__23*B__123 - A__3*B__13)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__123*B__13 + A__13*B__123 + A__2*B + A__23*B__3 - A__3*B__23)*e_2 + (A*B__3 + A__1*B__13 - A__12*B__123 - A__123*B__12 - A__13*B__1 + A__2*B__23 - A__23*B__2 + A__3*B)*e_3 + (A*B__12 + A__1*B__2 + A__12*B + A__123*B__3 - A__13*B__23 - A__2*B__1 + A__23*B__13 + A__3*B__123)*e_1^e_2 + (A*B__13 + A__1*B__3 + A__12*B__23 - A__123*B__2 + A__13*B - A__2*B__123 - A__23*B__12 - A__3*B__1)*e_1^e_3 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 + A__13*B__12 + A__2*B__3 + A__23*B - A__3*B__2)*e_2^e_3 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B - A__13*B__2 - A__2*B__13 + A__23*B__1 + A__3*B__12)*e_1^e_2^e_3"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(Cl3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1.388004 seconds (157 allocations: 5.859 KiB)"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} + A^{12} B^{12} - A^{123} B^{123} - A^{1234} B^{1234} - A^{124} B^{124} + A^{13} B^{13} - A^{134} B^{134} + A^{14} B^{14} - A^{2} B^{2} - A^{23} B^{23} + A^{234} B^{234} - A^{24} B^{24} - A^{3} B^{3} - A^{34} B^{34} - A^{4} B^{4}\\right )  + \\left ( A B^{1} + A^{1} B - A^{12} B^{2} - A^{123} B^{23} + A^{1234} B^{234} - A^{124} B^{24} - A^{13} B^{3} - A^{134} B^{34} - A^{14} B^{4} + A^{2} B^{12} - A^{23} B^{123} - A^{234} B^{1234} - A^{24} B^{124} + A^{3} B^{13} - A^{34} B^{134} + A^{4} B^{14}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} - A^{123} B^{13} + A^{1234} B^{134} - A^{124} B^{14} - A^{13} B^{123} - A^{134} B^{1234} - A^{14} B^{124} + A^{2} B - A^{23} B^{3} - A^{234} B^{34} - A^{24} B^{4} + A^{3} B^{23} - A^{34} B^{234} + A^{4} B^{24}\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} + A^{12} B^{123} + A^{123} B^{12} - A^{1234} B^{124} + A^{124} B^{1234} - A^{13} B^{1} - A^{134} B^{14} - A^{14} B^{134} - A^{2} B^{23} + A^{23} B^{2} + A^{234} B^{24} + A^{24} B^{234} + A^{3} B - A^{34} B^{4} + A^{4} B^{34}\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{4} + A^{1} B^{14} + A^{12} B^{124} - A^{123} B^{1234} + A^{1234} B^{123} + A^{124} B^{12} + A^{13} B^{134} + A^{134} B^{13} - A^{14} B^{1} - A^{2} B^{24} - A^{23} B^{234} - A^{234} B^{23} + A^{24} B^{2} - A^{3} B^{34} + A^{34} B^{3} + A^{4} B\\right ) \\boldsymbol{e}_{4} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B - A^{123} B^{3} - A^{1234} B^{34} - A^{124} B^{4} + A^{13} B^{23} - A^{134} B^{234} + A^{14} B^{24} - A^{2} B^{1} - A^{23} B^{13} + A^{234} B^{134} - A^{24} B^{14} - A^{3} B^{123} - A^{34} B^{1234} - A^{4} B^{124}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} - A^{12} B^{23} + A^{123} B^{2} + A^{1234} B^{24} + A^{124} B^{234} + A^{13} B - A^{134} B^{4} + A^{14} B^{34} + A^{2} B^{123} + A^{23} B^{12} - A^{234} B^{124} + A^{24} B^{1234} - A^{3} B^{1} - A^{34} B^{14} - A^{4} B^{134}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{14} + A^{1} B^{4} - A^{12} B^{24} - A^{123} B^{234} - A^{1234} B^{23} + A^{124} B^{2} - A^{13} B^{34} + A^{134} B^{3} + A^{14} B + A^{2} B^{124} - A^{23} B^{1234} + A^{234} B^{123} + A^{24} B^{12} + A^{3} B^{134} + A^{34} B^{13} - A^{4} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} + A^{1234} B^{14} + A^{124} B^{134} + A^{13} B^{12} - A^{134} B^{124} + A^{14} B^{1234} + A^{2} B^{3} + A^{23} B - A^{234} B^{4} + A^{24} B^{34} - A^{3} B^{2} - A^{34} B^{24} - A^{4} B^{234}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{24} + A^{1} B^{124} - A^{12} B^{14} - A^{123} B^{134} - A^{1234} B^{13} + A^{124} B^{1} - A^{13} B^{1234} + A^{134} B^{123} + A^{14} B^{12} + A^{2} B^{4} - A^{23} B^{34} + A^{234} B^{3} + A^{24} B + A^{3} B^{234} + A^{34} B^{23} - A^{4} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{34} + A^{1} B^{134} + A^{12} B^{1234} + A^{123} B^{124} + A^{1234} B^{12} - A^{124} B^{123} - A^{13} B^{14} + A^{134} B^{1} + A^{14} B^{13} - A^{2} B^{234} + A^{23} B^{24} - A^{234} B^{2} - A^{24} B^{23} + A^{3} B^{4} + A^{34} B - A^{4} B^{3}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B - A^{1234} B^{4} + A^{124} B^{34} - A^{13} B^{2} - A^{134} B^{24} - A^{14} B^{234} - A^{2} B^{13} + A^{23} B^{1} + A^{234} B^{14} + A^{24} B^{134} + A^{3} B^{12} - A^{34} B^{124} + A^{4} B^{1234}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{124} + A^{1} B^{24} + A^{12} B^{4} - A^{123} B^{34} + A^{1234} B^{3} + A^{124} B + A^{13} B^{234} + A^{134} B^{23} - A^{14} B^{2} - A^{2} B^{14} - A^{23} B^{134} - A^{234} B^{13} + A^{24} B^{1} - A^{3} B^{1234} + A^{34} B^{123} + A^{4} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{134} + A^{1} B^{34} - A^{12} B^{234} + A^{123} B^{24} - A^{1234} B^{2} - A^{124} B^{23} + A^{13} B^{4} + A^{134} B - A^{14} B^{3} + A^{2} B^{1234} + A^{23} B^{124} + A^{234} B^{12} - A^{24} B^{123} - A^{3} B^{14} + A^{34} B^{1} + A^{4} B^{13}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{234} + A^{1} B^{1234} - A^{12} B^{134} + A^{123} B^{14} - A^{1234} B^{1} - A^{124} B^{13} + A^{13} B^{124} + A^{134} B^{12} - A^{14} B^{123} + A^{2} B^{34} + A^{23} B^{4} + A^{234} B - A^{24} B^{3} - A^{3} B^{24} + A^{34} B^{2} + A^{4} B^{23}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{1234} + A^{1} B^{234} + A^{12} B^{34} + A^{123} B^{4} + A^{1234} B - A^{124} B^{3} - A^{13} B^{24} + A^{134} B^{2} + A^{14} B^{23} - A^{2} B^{134} + A^{23} B^{14} - A^{234} B^{1} - A^{24} B^{13} + A^{3} B^{124} + A^{34} B^{12} - A^{4} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 + A__12*B__12 - A__123*B__123 - A__1234*B__1234 - A__124*B__124 + A__13*B__13 - A__134*B__134 + A__14*B__14 - A__2*B__2 - A__23*B__23 + A__234*B__234 - A__24*B__24 - A__3*B__3 - A__34*B__34 - A__4*B__4 + (A*B__1 + A__1*B - A__12*B__2 - A__123*B__23 + A__1234*B__234 - A__124*B__24 - A__13*B__3 - A__134*B__34 - A__14*B__4 + A__2*B__12 - A__23*B__123 - A__234*B__1234 - A__24*B__124 + A__3*B__13 - A__34*B__134 + A__4*B__14)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 - A__123*B__13 + A__1234*B__134 - A__124*B__14 - A__13*B__123 - A__134*B__1234 - A__14*B__124 + A__2*B - A__23*B__3 - A__234*B__34 - A__24*B__4 + A__3*B__23 - A__34*B__234 + A__4*B__24)*e_2 + (A*B__3 + A__1*B__13 + A__12*B__123 + A__123*B__12 - A__1234*B__124 + A__124*B__1234 - A__13*B__1 - A__134*B__14 - A__14*B__134 - A__2*B__23 + A__23*B__2 + A__234*B__24 + A__24*B__234 + A__3*B - A__34*B__4 + A__4*B__34)*e_3 + (A*B__4 + A__1*B__14 + A__12*B__124 - A__123*B__1234 + A__1234*B__123 + A__124*B__12 + A__13*B__134 + A__134*B__13 - A__14*B__1 - A__2*B__24 - A__23*B__234 - A__234*B__23 + A__24*B__2 - A__3*B__34 + A__34*B__3 + A__4*B)*e_4 + (A*B__12 + A__1*B__2 + A__12*B - A__123*B__3 - A__1234*B__34 - A__124*B__4 + A__13*B__23 - A__134*B__234 + A__14*B__24 - A__2*B__1 - A__23*B__13 + A__234*B__134 - A__24*B__14 - A__3*B__123 - A__34*B__1234 - A__4*B__124)*e_1^e_2 + (A*B__13 + A__1*B__3 - A__12*B__23 + A__123*B__2 + A__1234*B__24 + A__124*B__234 + A__13*B - A__134*B__4 + A__14*B__34 + A__2*B__123 + A__23*B__12 - A__234*B__124 + A__24*B__1234 - A__3*B__1 - A__34*B__14 - A__4*B__134)*e_1^e_3 + (A*B__14 + A__1*B__4 - A__12*B__24 - A__123*B__234 - A__1234*B__23 + A__124*B__2 - A__13*B__34 + A__134*B__3 + A__14*B + A__2*B__124 - A__23*B__1234 + A__234*B__123 + A__24*B__12 + A__3*B__134 + A__34*B__13 - A__4*B__1)*e_1^e_4 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 + A__1234*B__14 + A__124*B__134 + A__13*B__12 - A__134*B__124 + A__14*B__1234 + A__2*B__3 + A__23*B - A__234*B__4 + A__24*B__34 - A__3*B__2 - A__34*B__24 - A__4*B__234)*e_2^e_3 + (A*B__24 + A__1*B__124 - A__12*B__14 - A__123*B__134 - A__1234*B__13 + A__124*B__1 - A__13*B__1234 + A__134*B__123 + A__14*B__12 + A__2*B__4 - A__23*B__34 + A__234*B__3 + A__24*B + A__3*B__234 + A__34*B__23 - A__4*B__2)*e_2^e_4 + (A*B__34 + A__1*B__134 + A__12*B__1234 + A__123*B__124 + A__1234*B__12 - A__124*B__123 - A__13*B__14 + A__134*B__1 + A__14*B__13 - A__2*B__234 + A__23*B__24 - A__234*B__2 - A__24*B__23 + A__3*B__4 + A__34*B - A__4*B__3)*e_3^e_4 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B - A__1234*B__4 + A__124*B__34 - A__13*B__2 - A__134*B__24 - A__14*B__234 - A__2*B__13 + A__23*B__1 + A__234*B__14 + A__24*B__134 + A__3*B__12 - A__34*B__124 + A__4*B__1234)*e_1^e_2^e_3 + (A*B__124 + A__1*B__24 + A__12*B__4 - A__123*B__34 + A__1234*B__3 + A__124*B + A__13*B__234 + A__134*B__23 - A__14*B__2 - A__2*B__14 - A__23*B__134 - A__234*B__13 + A__24*B__1 - A__3*B__1234 + A__34*B__123 + A__4*B__12)*e_1^e_2^e_4 + (A*B__134 + A__1*B__34 - A__12*B__234 + A__123*B__24 - A__1234*B__2 - A__124*B__23 + A__13*B__4 + A__134*B - A__14*B__3 + A__2*B__1234 + A__23*B__124 + A__234*B__12 - A__24*B__123 - A__3*B__14 + A__34*B__1 + A__4*B__13)*e_1^e_3^e_4 + (A*B__234 + A__1*B__1234 - A__12*B__134 + A__123*B__14 - A__1234*B__1 - A__124*B__13 + A__13*B__124 + A__134*B__12 - A__14*B__123 + A__2*B__34 + A__23*B__4 + A__234*B - A__24*B__3 - A__3*B__24 + A__34*B__2 + A__4*B__23)*e_2^e_3^e_4 + (A*B__1234 + A__1*B__234 + A__12*B__34 + A__123*B__4 + A__1234*B - A__124*B__3 - A__13*B__24 + A__134*B__2 + A__14*B__23 - A__2*B__134 + A__23*B__14 - A__234*B__1 - A__24*B__13 + A__3*B__124 + A__34*B__12 - A__4*B__123)*e_1^e_2^e_3^e_4"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n"
     ]
    }
   ],
   "source": [
    "@time test_geometric_product(Spacetime)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.112692 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} + A^{2} B^{2}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{2} B^{12}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{2} B\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} - A^{12} B^{123} - A^{123} B^{12} - A^{13} B^{1} + A^{2} B^{23} - A^{23} B^{2} + A^{3} B\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B - A^{2} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} + A^{12} B^{23} - A^{123} B^{2} + A^{13} B - A^{2} B^{123} - A^{23} B^{12} - A^{3} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} + A^{13} B^{12} + A^{2} B^{3} + A^{23} B - A^{3} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B - A^{13} B^{2} - A^{2} B^{13} + A^{23} B^{1} + A^{3} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 + A__2*B__2 + (A*B__1 + A__1*B + A__12*B__2 - A__2*B__12)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__2*B)*e_2 + (A*B__3 + A__1*B__13 - A__12*B__123 - A__123*B__12 - A__13*B__1 + A__2*B__23 - A__23*B__2 + A__3*B)*e_3 + (A*B__12 + A__1*B__2 + A__12*B - A__2*B__1)*e_1^e_2 + (A*B__13 + A__1*B__3 + A__12*B__23 - A__123*B__2 + A__13*B - A__2*B__123 - A__23*B__12 - A__3*B__1)*e_1^e_3 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 + A__13*B__12 + A__2*B__3 + A__23*B - A__3*B__2)*e_2^e_3 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B - A__13*B__2 - A__2*B__13 + A__23*B__1 + A__3*B__12)*e_1^e_2^e_3"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(PGA2D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  0.857979 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} - A^{123} B^{123} - A^{13} B^{13} + A^{2} B^{2} - A^{23} B^{23} + A^{3} B^{3}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{123} B^{23} + A^{13} B^{3} - A^{2} B^{12} - A^{23} B^{123} - A^{3} B^{13}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{123} B^{13} + A^{13} B^{123} + A^{2} B + A^{23} B^{3} - A^{3} B^{23}\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} - A^{12} B^{123} - A^{123} B^{12} - A^{13} B^{1} + A^{2} B^{23} - A^{23} B^{2} + A^{3} B\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{4} + A^{1} B^{14} - A^{12} B^{124} - A^{123} B^{1234} + A^{1234} B^{123} - A^{124} B^{12} - A^{13} B^{134} - A^{134} B^{13} - A^{14} B^{1} + A^{2} B^{24} - A^{23} B^{234} - A^{234} B^{23} - A^{24} B^{2} + A^{3} B^{34} - A^{34} B^{3} + A^{4} B\\right ) \\boldsymbol{e}_{4} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B + A^{123} B^{3} - A^{13} B^{23} - A^{2} B^{1} + A^{23} B^{13} + A^{3} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} + A^{12} B^{23} - A^{123} B^{2} + A^{13} B - A^{2} B^{123} - A^{23} B^{12} - A^{3} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{14} + A^{1} B^{4} + A^{12} B^{24} - A^{123} B^{234} - A^{1234} B^{23} - A^{124} B^{2} + A^{13} B^{34} - A^{134} B^{3} + A^{14} B - A^{2} B^{124} - A^{23} B^{1234} + A^{234} B^{123} - A^{24} B^{12} - A^{3} B^{134} - A^{34} B^{13} - A^{4} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} + A^{13} B^{12} + A^{2} B^{3} + A^{23} B - A^{3} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{24} + A^{1} B^{124} - A^{12} B^{14} + A^{123} B^{134} + A^{1234} B^{13} + A^{124} B^{1} + A^{13} B^{1234} - A^{134} B^{123} + A^{14} B^{12} + A^{2} B^{4} + A^{23} B^{34} - A^{234} B^{3} + A^{24} B - A^{3} B^{234} - A^{34} B^{23} - A^{4} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{34} + A^{1} B^{134} - A^{12} B^{1234} - A^{123} B^{124} - A^{1234} B^{12} + A^{124} B^{123} - A^{13} B^{14} + A^{134} B^{1} + A^{14} B^{13} + A^{2} B^{234} - A^{23} B^{24} + A^{234} B^{2} + A^{24} B^{23} + A^{3} B^{4} + A^{34} B - A^{4} B^{3}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B - A^{13} B^{2} - A^{2} B^{13} + A^{23} B^{1} + A^{3} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{124} + A^{1} B^{24} + A^{12} B^{4} + A^{123} B^{34} - A^{1234} B^{3} + A^{124} B - A^{13} B^{234} - A^{134} B^{23} - A^{14} B^{2} - A^{2} B^{14} + A^{23} B^{134} + A^{234} B^{13} + A^{24} B^{1} + A^{3} B^{1234} - A^{34} B^{123} + A^{4} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{134} + A^{1} B^{34} + A^{12} B^{234} - A^{123} B^{24} + A^{1234} B^{2} + A^{124} B^{23} + A^{13} B^{4} + A^{134} B - A^{14} B^{3} - A^{2} B^{1234} - A^{23} B^{124} - A^{234} B^{12} + A^{24} B^{123} - A^{3} B^{14} + A^{34} B^{1} + A^{4} B^{13}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{234} + A^{1} B^{1234} - A^{12} B^{134} + A^{123} B^{14} - A^{1234} B^{1} - A^{124} B^{13} + A^{13} B^{124} + A^{134} B^{12} - A^{14} B^{123} + A^{2} B^{34} + A^{23} B^{4} + A^{234} B - A^{24} B^{3} - A^{3} B^{24} + A^{34} B^{2} + A^{4} B^{23}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{1234} + A^{1} B^{234} + A^{12} B^{34} + A^{123} B^{4} + A^{1234} B - A^{124} B^{3} - A^{13} B^{24} + A^{134} B^{2} + A^{14} B^{23} - A^{2} B^{134} + A^{23} B^{14} - A^{234} B^{1} - A^{24} B^{13} + A^{3} B^{124} + A^{34} B^{12} - A^{4} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 - A__123*B__123 - A__13*B__13 + A__2*B__2 - A__23*B__23 + A__3*B__3 + (A*B__1 + A__1*B + A__12*B__2 - A__123*B__23 + A__13*B__3 - A__2*B__12 - A__23*B__123 - A__3*B__13)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__123*B__13 + A__13*B__123 + A__2*B + A__23*B__3 - A__3*B__23)*e_2 + (A*B__3 + A__1*B__13 - A__12*B__123 - A__123*B__12 - A__13*B__1 + A__2*B__23 - A__23*B__2 + A__3*B)*e_3 + (A*B__4 + A__1*B__14 - A__12*B__124 - A__123*B__1234 + A__1234*B__123 - A__124*B__12 - A__13*B__134 - A__134*B__13 - A__14*B__1 + A__2*B__24 - A__23*B__234 - A__234*B__23 - A__24*B__2 + A__3*B__34 - A__34*B__3 + A__4*B)*e_4 + (A*B__12 + A__1*B__2 + A__12*B + A__123*B__3 - A__13*B__23 - A__2*B__1 + A__23*B__13 + A__3*B__123)*e_1^e_2 + (A*B__13 + A__1*B__3 + A__12*B__23 - A__123*B__2 + A__13*B - A__2*B__123 - A__23*B__12 - A__3*B__1)*e_1^e_3 + (A*B__14 + A__1*B__4 + A__12*B__24 - A__123*B__234 - A__1234*B__23 - A__124*B__2 + A__13*B__34 - A__134*B__3 + A__14*B - A__2*B__124 - A__23*B__1234 + A__234*B__123 - A__24*B__12 - A__3*B__134 - A__34*B__13 - A__4*B__1)*e_1^e_4 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 + A__13*B__12 + A__2*B__3 + A__23*B - A__3*B__2)*e_2^e_3 + (A*B__24 + A__1*B__124 - A__12*B__14 + A__123*B__134 + A__1234*B__13 + A__124*B__1 + A__13*B__1234 - A__134*B__123 + A__14*B__12 + A__2*B__4 + A__23*B__34 - A__234*B__3 + A__24*B - A__3*B__234 - A__34*B__23 - A__4*B__2)*e_2^e_4 + (A*B__34 + A__1*B__134 - A__12*B__1234 - A__123*B__124 - A__1234*B__12 + A__124*B__123 - A__13*B__14 + A__134*B__1 + A__14*B__13 + A__2*B__234 - A__23*B__24 + A__234*B__2 + A__24*B__23 + A__3*B__4 + A__34*B - A__4*B__3)*e_3^e_4 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B - A__13*B__2 - A__2*B__13 + A__23*B__1 + A__3*B__12)*e_1^e_2^e_3 + (A*B__124 + A__1*B__24 + A__12*B__4 + A__123*B__34 - A__1234*B__3 + A__124*B - A__13*B__234 - A__134*B__23 - A__14*B__2 - A__2*B__14 + A__23*B__134 + A__234*B__13 + A__24*B__1 + A__3*B__1234 - A__34*B__123 + A__4*B__12)*e_1^e_2^e_4 + (A*B__134 + A__1*B__34 + A__12*B__234 - A__123*B__24 + A__1234*B__2 + A__124*B__23 + A__13*B__4 + A__134*B - A__14*B__3 - A__2*B__1234 - A__23*B__124 - A__234*B__12 + A__24*B__123 - A__3*B__14 + A__34*B__1 + A__4*B__13)*e_1^e_3^e_4 + (A*B__234 + A__1*B__1234 - A__12*B__134 + A__123*B__14 - A__1234*B__1 - A__124*B__13 + A__13*B__124 + A__134*B__12 - A__14*B__123 + A__2*B__34 + A__23*B__4 + A__234*B - A__24*B__3 - A__3*B__24 + A__34*B__2 + A__4*B__23)*e_2^e_3^e_4 + (A*B__1234 + A__1*B__234 + A__12*B__34 + A__123*B__4 + A__1234*B - A__124*B__3 - A__13*B__24 + A__134*B__2 + A__14*B__23 - A__2*B__134 + A__23*B__14 - A__234*B__1 - A__24*B__13 + A__3*B__124 + A__34*B__12 - A__4*B__123)*e_1^e_2^e_3^e_4"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(PGA3D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  1.281144 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} - A^{123} B^{123} - A^{1234} B^{1234} + A^{124} B^{124} - A^{13} B^{13} + A^{134} B^{134} + A^{14} B^{14} + A^{2} B^{2} - A^{23} B^{23} + A^{234} B^{234} + A^{24} B^{24} + A^{3} B^{3} + A^{34} B^{34} - A^{4} B^{4}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{123} B^{23} + A^{1234} B^{234} + A^{124} B^{24} + A^{13} B^{3} + A^{134} B^{34} - A^{14} B^{4} - A^{2} B^{12} - A^{23} B^{123} - A^{234} B^{1234} + A^{24} B^{124} - A^{3} B^{13} + A^{34} B^{134} + A^{4} B^{14}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{123} B^{13} - A^{1234} B^{134} - A^{124} B^{14} + A^{13} B^{123} + A^{134} B^{1234} - A^{14} B^{124} + A^{2} B + A^{23} B^{3} + A^{234} B^{34} - A^{24} B^{4} - A^{3} B^{23} + A^{34} B^{234} + A^{4} B^{24}\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} - A^{12} B^{123} - A^{123} B^{12} + A^{1234} B^{124} - A^{124} B^{1234} - A^{13} B^{1} - A^{134} B^{14} - A^{14} B^{134} + A^{2} B^{23} - A^{23} B^{2} - A^{234} B^{24} - A^{24} B^{234} + A^{3} B - A^{34} B^{4} + A^{4} B^{34}\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{4} + A^{1} B^{14} - A^{12} B^{124} - A^{123} B^{1234} + A^{1234} B^{123} - A^{124} B^{12} - A^{13} B^{134} - A^{134} B^{13} - A^{14} B^{1} + A^{2} B^{24} - A^{23} B^{234} - A^{234} B^{23} - A^{24} B^{2} + A^{3} B^{34} - A^{34} B^{3} + A^{4} B\\right ) \\boldsymbol{e}_{4} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B + A^{123} B^{3} + A^{1234} B^{34} - A^{124} B^{4} - A^{13} B^{23} + A^{134} B^{234} + A^{14} B^{24} - A^{2} B^{1} + A^{23} B^{13} - A^{234} B^{134} - A^{24} B^{14} + A^{3} B^{123} + A^{34} B^{1234} - A^{4} B^{124}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} + A^{12} B^{23} - A^{123} B^{2} - A^{1234} B^{24} - A^{124} B^{234} + A^{13} B - A^{134} B^{4} + A^{14} B^{34} - A^{2} B^{123} - A^{23} B^{12} + A^{234} B^{124} - A^{24} B^{1234} - A^{3} B^{1} - A^{34} B^{14} - A^{4} B^{134}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{14} + A^{1} B^{4} + A^{12} B^{24} - A^{123} B^{234} - A^{1234} B^{23} - A^{124} B^{2} + A^{13} B^{34} - A^{134} B^{3} + A^{14} B - A^{2} B^{124} - A^{23} B^{1234} + A^{234} B^{123} - A^{24} B^{12} - A^{3} B^{134} - A^{34} B^{13} - A^{4} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} + A^{1234} B^{14} + A^{124} B^{134} + A^{13} B^{12} - A^{134} B^{124} + A^{14} B^{1234} + A^{2} B^{3} + A^{23} B - A^{234} B^{4} + A^{24} B^{34} - A^{3} B^{2} - A^{34} B^{24} - A^{4} B^{234}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{24} + A^{1} B^{124} - A^{12} B^{14} + A^{123} B^{134} + A^{1234} B^{13} + A^{124} B^{1} + A^{13} B^{1234} - A^{134} B^{123} + A^{14} B^{12} + A^{2} B^{4} + A^{23} B^{34} - A^{234} B^{3} + A^{24} B - A^{3} B^{234} - A^{34} B^{23} - A^{4} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{34} + A^{1} B^{134} - A^{12} B^{1234} - A^{123} B^{124} - A^{1234} B^{12} + A^{124} B^{123} - A^{13} B^{14} + A^{134} B^{1} + A^{14} B^{13} + A^{2} B^{234} - A^{23} B^{24} + A^{234} B^{2} + A^{24} B^{23} + A^{3} B^{4} + A^{34} B - A^{4} B^{3}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B - A^{1234} B^{4} + A^{124} B^{34} - A^{13} B^{2} - A^{134} B^{24} - A^{14} B^{234} - A^{2} B^{13} + A^{23} B^{1} + A^{234} B^{14} + A^{24} B^{134} + A^{3} B^{12} - A^{34} B^{124} + A^{4} B^{1234}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{124} + A^{1} B^{24} + A^{12} B^{4} + A^{123} B^{34} - A^{1234} B^{3} + A^{124} B - A^{13} B^{234} - A^{134} B^{23} - A^{14} B^{2} - A^{2} B^{14} + A^{23} B^{134} + A^{234} B^{13} + A^{24} B^{1} + A^{3} B^{1234} - A^{34} B^{123} + A^{4} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{134} + A^{1} B^{34} + A^{12} B^{234} - A^{123} B^{24} + A^{1234} B^{2} + A^{124} B^{23} + A^{13} B^{4} + A^{134} B - A^{14} B^{3} - A^{2} B^{1234} - A^{23} B^{124} - A^{234} B^{12} + A^{24} B^{123} - A^{3} B^{14} + A^{34} B^{1} + A^{4} B^{13}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{234} + A^{1} B^{1234} - A^{12} B^{134} + A^{123} B^{14} - A^{1234} B^{1} - A^{124} B^{13} + A^{13} B^{124} + A^{134} B^{12} - A^{14} B^{123} + A^{2} B^{34} + A^{23} B^{4} + A^{234} B - A^{24} B^{3} - A^{3} B^{24} + A^{34} B^{2} + A^{4} B^{23}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{1234} + A^{1} B^{234} + A^{12} B^{34} + A^{123} B^{4} + A^{1234} B - A^{124} B^{3} - A^{13} B^{24} + A^{134} B^{2} + A^{14} B^{23} - A^{2} B^{134} + A^{23} B^{14} - A^{234} B^{1} - A^{24} B^{13} + A^{3} B^{124} + A^{34} B^{12} - A^{4} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 - A__123*B__123 - A__1234*B__1234 + A__124*B__124 - A__13*B__13 + A__134*B__134 + A__14*B__14 + A__2*B__2 - A__23*B__23 + A__234*B__234 + A__24*B__24 + A__3*B__3 + A__34*B__34 - A__4*B__4 + (A*B__1 + A__1*B + A__12*B__2 - A__123*B__23 + A__1234*B__234 + A__124*B__24 + A__13*B__3 + A__134*B__34 - A__14*B__4 - A__2*B__12 - A__23*B__123 - A__234*B__1234 + A__24*B__124 - A__3*B__13 + A__34*B__134 + A__4*B__14)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__123*B__13 - A__1234*B__134 - A__124*B__14 + A__13*B__123 + A__134*B__1234 - A__14*B__124 + A__2*B + A__23*B__3 + A__234*B__34 - A__24*B__4 - A__3*B__23 + A__34*B__234 + A__4*B__24)*e_2 + (A*B__3 + A__1*B__13 - A__12*B__123 - A__123*B__12 + A__1234*B__124 - A__124*B__1234 - A__13*B__1 - A__134*B__14 - A__14*B__134 + A__2*B__23 - A__23*B__2 - A__234*B__24 - A__24*B__234 + A__3*B - A__34*B__4 + A__4*B__34)*e_3 + (A*B__4 + A__1*B__14 - A__12*B__124 - A__123*B__1234 + A__1234*B__123 - A__124*B__12 - A__13*B__134 - A__134*B__13 - A__14*B__1 + A__2*B__24 - A__23*B__234 - A__234*B__23 - A__24*B__2 + A__3*B__34 - A__34*B__3 + A__4*B)*e_4 + (A*B__12 + A__1*B__2 + A__12*B + A__123*B__3 + A__1234*B__34 - A__124*B__4 - A__13*B__23 + A__134*B__234 + A__14*B__24 - A__2*B__1 + A__23*B__13 - A__234*B__134 - A__24*B__14 + A__3*B__123 + A__34*B__1234 - A__4*B__124)*e_1^e_2 + (A*B__13 + A__1*B__3 + A__12*B__23 - A__123*B__2 - A__1234*B__24 - A__124*B__234 + A__13*B - A__134*B__4 + A__14*B__34 - A__2*B__123 - A__23*B__12 + A__234*B__124 - A__24*B__1234 - A__3*B__1 - A__34*B__14 - A__4*B__134)*e_1^e_3 + (A*B__14 + A__1*B__4 + A__12*B__24 - A__123*B__234 - A__1234*B__23 - A__124*B__2 + A__13*B__34 - A__134*B__3 + A__14*B - A__2*B__124 - A__23*B__1234 + A__234*B__123 - A__24*B__12 - A__3*B__134 - A__34*B__13 - A__4*B__1)*e_1^e_4 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 + A__1234*B__14 + A__124*B__134 + A__13*B__12 - A__134*B__124 + A__14*B__1234 + A__2*B__3 + A__23*B - A__234*B__4 + A__24*B__34 - A__3*B__2 - A__34*B__24 - A__4*B__234)*e_2^e_3 + (A*B__24 + A__1*B__124 - A__12*B__14 + A__123*B__134 + A__1234*B__13 + A__124*B__1 + A__13*B__1234 - A__134*B__123 + A__14*B__12 + A__2*B__4 + A__23*B__34 - A__234*B__3 + A__24*B - A__3*B__234 - A__34*B__23 - A__4*B__2)*e_2^e_4 + (A*B__34 + A__1*B__134 - A__12*B__1234 - A__123*B__124 - A__1234*B__12 + A__124*B__123 - A__13*B__14 + A__134*B__1 + A__14*B__13 + A__2*B__234 - A__23*B__24 + A__234*B__2 + A__24*B__23 + A__3*B__4 + A__34*B - A__4*B__3)*e_3^e_4 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B - A__1234*B__4 + A__124*B__34 - A__13*B__2 - A__134*B__24 - A__14*B__234 - A__2*B__13 + A__23*B__1 + A__234*B__14 + A__24*B__134 + A__3*B__12 - A__34*B__124 + A__4*B__1234)*e_1^e_2^e_3 + (A*B__124 + A__1*B__24 + A__12*B__4 + A__123*B__34 - A__1234*B__3 + A__124*B - A__13*B__234 - A__134*B__23 - A__14*B__2 - A__2*B__14 + A__23*B__134 + A__234*B__13 + A__24*B__1 + A__3*B__1234 - A__34*B__123 + A__4*B__12)*e_1^e_2^e_4 + (A*B__134 + A__1*B__34 + A__12*B__234 - A__123*B__24 + A__1234*B__2 + A__124*B__23 + A__13*B__4 + A__134*B - A__14*B__3 - A__2*B__1234 - A__23*B__124 - A__234*B__12 + A__24*B__123 - A__3*B__14 + A__34*B__1 + A__4*B__13)*e_1^e_3^e_4 + (A*B__234 + A__1*B__1234 - A__12*B__134 + A__123*B__14 - A__1234*B__1 - A__124*B__13 + A__13*B__124 + A__134*B__12 - A__14*B__123 + A__2*B__34 + A__23*B__4 + A__234*B - A__24*B__3 - A__3*B__24 + A__34*B__2 + A__4*B__23)*e_2^e_3^e_4 + (A*B__1234 + A__1*B__234 + A__12*B__34 + A__123*B__4 + A__1234*B - A__124*B__3 - A__13*B__24 + A__134*B__2 + A__14*B__23 - A__2*B__134 + A__23*B__14 - A__234*B__1 - A__24*B__13 + A__3*B__124 + A__34*B__12 - A__4*B__123)*e_1^e_2^e_3^e_4"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(CGA2D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 14.452170 seconds (157 allocations: 5.859 KiB)\n"
     ]
    },
    {
     "data": {
      "text/latex": [
       "\\begin{align*}\\left ( A B + A^{1} B^{1} - A^{12} B^{12} - A^{123} B^{123} + A^{1234} B^{1234} - A^{12345} B^{12345} - A^{1235} B^{1235} - A^{124} B^{124} - A^{1245} B^{1245} + A^{125} B^{125} - A^{13} B^{13} - A^{134} B^{134} - A^{1345} B^{1345} + A^{135} B^{135} - A^{14} B^{14} + A^{145} B^{145} + A^{15} B^{15} + A^{2} B^{2} - A^{23} B^{23} - A^{234} B^{234} - A^{2345} B^{2345} + A^{235} B^{235} - A^{24} B^{24} + A^{245} B^{245} + A^{25} B^{25} + A^{3} B^{3} - A^{34} B^{34} + A^{345} B^{345} + A^{35} B^{35} + A^{4} B^{4} + A^{45} B^{45} - A^{5} B^{5}\\right )  + \\left ( A B^{1} + A^{1} B + A^{12} B^{2} - A^{123} B^{23} - A^{1234} B^{234} - A^{12345} B^{2345} + A^{1235} B^{235} - A^{124} B^{24} + A^{1245} B^{245} + A^{125} B^{25} + A^{13} B^{3} - A^{134} B^{34} + A^{1345} B^{345} + A^{135} B^{35} + A^{14} B^{4} + A^{145} B^{45} - A^{15} B^{5} - A^{2} B^{12} - A^{23} B^{123} + A^{234} B^{1234} - A^{2345} B^{12345} - A^{235} B^{1235} - A^{24} B^{124} - A^{245} B^{1245} + A^{25} B^{125} - A^{3} B^{13} - A^{34} B^{134} - A^{345} B^{1345} + A^{35} B^{135} - A^{4} B^{14} + A^{45} B^{145} + A^{5} B^{15}\\right ) \\boldsymbol{e}_{1} + \\left ( A B^{2} + A^{1} B^{12} - A^{12} B^{1} + A^{123} B^{13} + A^{1234} B^{134} + A^{12345} B^{1345} - A^{1235} B^{135} + A^{124} B^{14} - A^{1245} B^{145} - A^{125} B^{15} + A^{13} B^{123} - A^{134} B^{1234} + A^{1345} B^{12345} + A^{135} B^{1235} + A^{14} B^{124} + A^{145} B^{1245} - A^{15} B^{125} + A^{2} B + A^{23} B^{3} - A^{234} B^{34} + A^{2345} B^{345} + A^{235} B^{35} + A^{24} B^{4} + A^{245} B^{45} - A^{25} B^{5} - A^{3} B^{23} - A^{34} B^{234} - A^{345} B^{2345} + A^{35} B^{235} - A^{4} B^{24} + A^{45} B^{245} + A^{5} B^{25}\\right ) \\boldsymbol{e}_{2} + \\left ( A B^{3} + A^{1} B^{13} - A^{12} B^{123} - A^{123} B^{12} - A^{1234} B^{124} - A^{12345} B^{1245} + A^{1235} B^{125} + A^{124} B^{1234} - A^{1245} B^{12345} - A^{125} B^{1235} - A^{13} B^{1} + A^{134} B^{14} - A^{1345} B^{145} - A^{135} B^{15} + A^{14} B^{134} + A^{145} B^{1345} - A^{15} B^{135} + A^{2} B^{23} - A^{23} B^{2} + A^{234} B^{24} - A^{2345} B^{245} - A^{235} B^{25} + A^{24} B^{234} + A^{245} B^{2345} - A^{25} B^{235} + A^{3} B + A^{34} B^{4} + A^{345} B^{45} - A^{35} B^{5} - A^{4} B^{34} + A^{45} B^{345} + A^{5} B^{35}\\right ) \\boldsymbol{e}_{3} + \\left ( A B^{4} + A^{1} B^{14} - A^{12} B^{124} - A^{123} B^{1234} + A^{1234} B^{123} + A^{12345} B^{1235} + A^{1235} B^{12345} - A^{124} B^{12} + A^{1245} B^{125} - A^{125} B^{1245} - A^{13} B^{134} - A^{134} B^{13} + A^{1345} B^{135} - A^{135} B^{1345} - A^{14} B^{1} - A^{145} B^{15} - A^{15} B^{145} + A^{2} B^{24} - A^{23} B^{234} - A^{234} B^{23} + A^{2345} B^{235} - A^{235} B^{2345} - A^{24} B^{2} - A^{245} B^{25} - A^{25} B^{245} + A^{3} B^{34} - A^{34} B^{3} - A^{345} B^{35} - A^{35} B^{345} + A^{4} B - A^{45} B^{5} + A^{5} B^{45}\\right ) \\boldsymbol{e}_{4} + \\left ( A B^{5} + A^{1} B^{15} - A^{12} B^{125} - A^{123} B^{1235} + A^{1234} B^{12345} + A^{12345} B^{1234} + A^{1235} B^{123} - A^{124} B^{1245} + A^{1245} B^{124} - A^{125} B^{12} - A^{13} B^{135} - A^{134} B^{1345} + A^{1345} B^{134} - A^{135} B^{13} - A^{14} B^{145} - A^{145} B^{14} - A^{15} B^{1} + A^{2} B^{25} - A^{23} B^{235} - A^{234} B^{2345} + A^{2345} B^{234} - A^{235} B^{23} - A^{24} B^{245} - A^{245} B^{24} - A^{25} B^{2} + A^{3} B^{35} - A^{34} B^{345} - A^{345} B^{34} - A^{35} B^{3} + A^{4} B^{45} - A^{45} B^{4} + A^{5} B\\right ) \\boldsymbol{e}_{5} + \\left ( A B^{12} + A^{1} B^{2} + A^{12} B + A^{123} B^{3} - A^{1234} B^{34} + A^{12345} B^{345} + A^{1235} B^{35} + A^{124} B^{4} + A^{1245} B^{45} - A^{125} B^{5} - A^{13} B^{23} - A^{134} B^{234} - A^{1345} B^{2345} + A^{135} B^{235} - A^{14} B^{24} + A^{145} B^{245} + A^{15} B^{25} - A^{2} B^{1} + A^{23} B^{13} + A^{234} B^{134} + A^{2345} B^{1345} - A^{235} B^{135} + A^{24} B^{14} - A^{245} B^{145} - A^{25} B^{15} + A^{3} B^{123} - A^{34} B^{1234} + A^{345} B^{12345} + A^{35} B^{1235} + A^{4} B^{124} + A^{45} B^{1245} - A^{5} B^{125}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2} + \\left ( A B^{13} + A^{1} B^{3} + A^{12} B^{23} - A^{123} B^{2} + A^{1234} B^{24} - A^{12345} B^{245} - A^{1235} B^{25} + A^{124} B^{234} + A^{1245} B^{2345} - A^{125} B^{235} + A^{13} B + A^{134} B^{4} + A^{1345} B^{45} - A^{135} B^{5} - A^{14} B^{34} + A^{145} B^{345} + A^{15} B^{35} - A^{2} B^{123} - A^{23} B^{12} - A^{234} B^{124} - A^{2345} B^{1245} + A^{235} B^{125} + A^{24} B^{1234} - A^{245} B^{12345} - A^{25} B^{1235} - A^{3} B^{1} + A^{34} B^{14} - A^{345} B^{145} - A^{35} B^{15} + A^{4} B^{134} + A^{45} B^{1345} - A^{5} B^{135}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{14} + A^{1} B^{4} + A^{12} B^{24} - A^{123} B^{234} - A^{1234} B^{23} + A^{12345} B^{235} - A^{1235} B^{2345} - A^{124} B^{2} - A^{1245} B^{25} - A^{125} B^{245} + A^{13} B^{34} - A^{134} B^{3} - A^{1345} B^{35} - A^{135} B^{345} + A^{14} B - A^{145} B^{5} + A^{15} B^{45} - A^{2} B^{124} - A^{23} B^{1234} + A^{234} B^{123} + A^{2345} B^{1235} + A^{235} B^{12345} - A^{24} B^{12} + A^{245} B^{125} - A^{25} B^{1245} - A^{3} B^{134} - A^{34} B^{13} + A^{345} B^{135} - A^{35} B^{1345} - A^{4} B^{1} - A^{45} B^{15} - A^{5} B^{145}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{15} + A^{1} B^{5} + A^{12} B^{25} - A^{123} B^{235} - A^{1234} B^{2345} + A^{12345} B^{234} - A^{1235} B^{23} - A^{124} B^{245} - A^{1245} B^{24} - A^{125} B^{2} + A^{13} B^{35} - A^{134} B^{345} - A^{1345} B^{34} - A^{135} B^{3} + A^{14} B^{45} - A^{145} B^{4} + A^{15} B - A^{2} B^{125} - A^{23} B^{1235} + A^{234} B^{12345} + A^{2345} B^{1234} + A^{235} B^{123} - A^{24} B^{1245} + A^{245} B^{124} - A^{25} B^{12} - A^{3} B^{135} - A^{34} B^{1345} + A^{345} B^{134} - A^{35} B^{13} - A^{4} B^{145} - A^{45} B^{14} - A^{5} B^{1}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{23} + A^{1} B^{123} - A^{12} B^{13} + A^{123} B^{1} - A^{1234} B^{14} + A^{12345} B^{145} + A^{1235} B^{15} - A^{124} B^{134} - A^{1245} B^{1345} + A^{125} B^{135} + A^{13} B^{12} + A^{134} B^{124} + A^{1345} B^{1245} - A^{135} B^{125} - A^{14} B^{1234} + A^{145} B^{12345} + A^{15} B^{1235} + A^{2} B^{3} + A^{23} B + A^{234} B^{4} + A^{2345} B^{45} - A^{235} B^{5} - A^{24} B^{34} + A^{245} B^{345} + A^{25} B^{35} - A^{3} B^{2} + A^{34} B^{24} - A^{345} B^{245} - A^{35} B^{25} + A^{4} B^{234} + A^{45} B^{2345} - A^{5} B^{235}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{24} + A^{1} B^{124} - A^{12} B^{14} + A^{123} B^{134} + A^{1234} B^{13} - A^{12345} B^{135} + A^{1235} B^{1345} + A^{124} B^{1} + A^{1245} B^{15} + A^{125} B^{145} + A^{13} B^{1234} - A^{134} B^{123} - A^{1345} B^{1235} - A^{135} B^{12345} + A^{14} B^{12} - A^{145} B^{125} + A^{15} B^{1245} + A^{2} B^{4} + A^{23} B^{34} - A^{234} B^{3} - A^{2345} B^{35} - A^{235} B^{345} + A^{24} B - A^{245} B^{5} + A^{25} B^{45} - A^{3} B^{234} - A^{34} B^{23} + A^{345} B^{235} - A^{35} B^{2345} - A^{4} B^{2} - A^{45} B^{25} - A^{5} B^{245}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{25} + A^{1} B^{125} - A^{12} B^{15} + A^{123} B^{135} + A^{1234} B^{1345} - A^{12345} B^{134} + A^{1235} B^{13} + A^{124} B^{145} + A^{1245} B^{14} + A^{125} B^{1} + A^{13} B^{1235} - A^{134} B^{12345} - A^{1345} B^{1234} - A^{135} B^{123} + A^{14} B^{1245} - A^{145} B^{124} + A^{15} B^{12} + A^{2} B^{5} + A^{23} B^{35} - A^{234} B^{345} - A^{2345} B^{34} - A^{235} B^{3} + A^{24} B^{45} - A^{245} B^{4} + A^{25} B - A^{3} B^{235} - A^{34} B^{2345} + A^{345} B^{234} - A^{35} B^{23} - A^{4} B^{245} - A^{45} B^{24} - A^{5} B^{2}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{34} + A^{1} B^{134} - A^{12} B^{1234} - A^{123} B^{124} - A^{1234} B^{12} + A^{12345} B^{125} - A^{1235} B^{1245} + A^{124} B^{123} + A^{1245} B^{1235} + A^{125} B^{12345} - A^{13} B^{14} + A^{134} B^{1} + A^{1345} B^{15} + A^{135} B^{145} + A^{14} B^{13} - A^{145} B^{135} + A^{15} B^{1345} + A^{2} B^{234} - A^{23} B^{24} + A^{234} B^{2} + A^{2345} B^{25} + A^{235} B^{245} + A^{24} B^{23} - A^{245} B^{235} + A^{25} B^{2345} + A^{3} B^{4} + A^{34} B - A^{345} B^{5} + A^{35} B^{45} - A^{4} B^{3} - A^{45} B^{35} - A^{5} B^{345}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{35} + A^{1} B^{135} - A^{12} B^{1235} - A^{123} B^{125} - A^{1234} B^{1245} + A^{12345} B^{124} - A^{1235} B^{12} + A^{124} B^{12345} + A^{1245} B^{1234} + A^{125} B^{123} - A^{13} B^{15} + A^{134} B^{145} + A^{1345} B^{14} + A^{135} B^{1} + A^{14} B^{1345} - A^{145} B^{134} + A^{15} B^{13} + A^{2} B^{235} - A^{23} B^{25} + A^{234} B^{245} + A^{2345} B^{24} + A^{235} B^{2} + A^{24} B^{2345} - A^{245} B^{234} + A^{25} B^{23} + A^{3} B^{5} + A^{34} B^{45} - A^{345} B^{4} + A^{35} B - A^{4} B^{345} - A^{45} B^{34} - A^{5} B^{3}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{45} + A^{1} B^{145} - A^{12} B^{1245} - A^{123} B^{12345} + A^{1234} B^{1235} - A^{12345} B^{123} - A^{1235} B^{1234} - A^{124} B^{125} - A^{1245} B^{12} + A^{125} B^{124} - A^{13} B^{1345} - A^{134} B^{135} - A^{1345} B^{13} + A^{135} B^{134} - A^{14} B^{15} + A^{145} B^{1} + A^{15} B^{14} + A^{2} B^{245} - A^{23} B^{2345} - A^{234} B^{235} - A^{2345} B^{23} + A^{235} B^{234} - A^{24} B^{25} + A^{245} B^{2} + A^{25} B^{24} + A^{3} B^{345} - A^{34} B^{35} + A^{345} B^{3} + A^{35} B^{34} + A^{4} B^{5} + A^{45} B - A^{5} B^{4}\\right ) \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{123} + A^{1} B^{23} + A^{12} B^{3} + A^{123} B + A^{1234} B^{4} + A^{12345} B^{45} - A^{1235} B^{5} - A^{124} B^{34} + A^{1245} B^{345} + A^{125} B^{35} - A^{13} B^{2} + A^{134} B^{24} - A^{1345} B^{245} - A^{135} B^{25} + A^{14} B^{234} + A^{145} B^{2345} - A^{15} B^{235} - A^{2} B^{13} + A^{23} B^{1} - A^{234} B^{14} + A^{2345} B^{145} + A^{235} B^{15} - A^{24} B^{134} - A^{245} B^{1345} + A^{25} B^{135} + A^{3} B^{12} + A^{34} B^{124} + A^{345} B^{1245} - A^{35} B^{125} - A^{4} B^{1234} + A^{45} B^{12345} + A^{5} B^{1235}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3} + \\left ( A B^{124} + A^{1} B^{24} + A^{12} B^{4} + A^{123} B^{34} - A^{1234} B^{3} - A^{12345} B^{35} - A^{1235} B^{345} + A^{124} B - A^{1245} B^{5} + A^{125} B^{45} - A^{13} B^{234} - A^{134} B^{23} + A^{1345} B^{235} - A^{135} B^{2345} - A^{14} B^{2} - A^{145} B^{25} - A^{15} B^{245} - A^{2} B^{14} + A^{23} B^{134} + A^{234} B^{13} - A^{2345} B^{135} + A^{235} B^{1345} + A^{24} B^{1} + A^{245} B^{15} + A^{25} B^{145} + A^{3} B^{1234} - A^{34} B^{123} - A^{345} B^{1235} - A^{35} B^{12345} + A^{4} B^{12} - A^{45} B^{125} + A^{5} B^{1245}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{125} + A^{1} B^{25} + A^{12} B^{5} + A^{123} B^{35} - A^{1234} B^{345} - A^{12345} B^{34} - A^{1235} B^{3} + A^{124} B^{45} - A^{1245} B^{4} + A^{125} B - A^{13} B^{235} - A^{134} B^{2345} + A^{1345} B^{234} - A^{135} B^{23} - A^{14} B^{245} - A^{145} B^{24} - A^{15} B^{2} - A^{2} B^{15} + A^{23} B^{135} + A^{234} B^{1345} - A^{2345} B^{134} + A^{235} B^{13} + A^{24} B^{145} + A^{245} B^{14} + A^{25} B^{1} + A^{3} B^{1235} - A^{34} B^{12345} - A^{345} B^{1234} - A^{35} B^{123} + A^{4} B^{1245} - A^{45} B^{124} + A^{5} B^{12}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{134} + A^{1} B^{34} + A^{12} B^{234} - A^{123} B^{24} + A^{1234} B^{2} + A^{12345} B^{25} + A^{1235} B^{245} + A^{124} B^{23} - A^{1245} B^{235} + A^{125} B^{2345} + A^{13} B^{4} + A^{134} B - A^{1345} B^{5} + A^{135} B^{45} - A^{14} B^{3} - A^{145} B^{35} - A^{15} B^{345} - A^{2} B^{1234} - A^{23} B^{124} - A^{234} B^{12} + A^{2345} B^{125} - A^{235} B^{1245} + A^{24} B^{123} + A^{245} B^{1235} + A^{25} B^{12345} - A^{3} B^{14} + A^{34} B^{1} + A^{345} B^{15} + A^{35} B^{145} + A^{4} B^{13} - A^{45} B^{135} + A^{5} B^{1345}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{135} + A^{1} B^{35} + A^{12} B^{235} - A^{123} B^{25} + A^{1234} B^{245} + A^{12345} B^{24} + A^{1235} B^{2} + A^{124} B^{2345} - A^{1245} B^{234} + A^{125} B^{23} + A^{13} B^{5} + A^{134} B^{45} - A^{1345} B^{4} + A^{135} B - A^{14} B^{345} - A^{145} B^{34} - A^{15} B^{3} - A^{2} B^{1235} - A^{23} B^{125} - A^{234} B^{1245} + A^{2345} B^{124} - A^{235} B^{12} + A^{24} B^{12345} + A^{245} B^{1234} + A^{25} B^{123} - A^{3} B^{15} + A^{34} B^{145} + A^{345} B^{14} + A^{35} B^{1} + A^{4} B^{1345} - A^{45} B^{134} + A^{5} B^{13}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{145} + A^{1} B^{45} + A^{12} B^{245} - A^{123} B^{2345} - A^{1234} B^{235} - A^{12345} B^{23} + A^{1235} B^{234} - A^{124} B^{25} + A^{1245} B^{2} + A^{125} B^{24} + A^{13} B^{345} - A^{134} B^{35} + A^{1345} B^{3} + A^{135} B^{34} + A^{14} B^{5} + A^{145} B - A^{15} B^{4} - A^{2} B^{1245} - A^{23} B^{12345} + A^{234} B^{1235} - A^{2345} B^{123} - A^{235} B^{1234} - A^{24} B^{125} - A^{245} B^{12} + A^{25} B^{124} - A^{3} B^{1345} - A^{34} B^{135} - A^{345} B^{13} + A^{35} B^{134} - A^{4} B^{15} + A^{45} B^{1} + A^{5} B^{14}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{234} + A^{1} B^{1234} - A^{12} B^{134} + A^{123} B^{14} - A^{1234} B^{1} - A^{12345} B^{15} - A^{1235} B^{145} - A^{124} B^{13} + A^{1245} B^{135} - A^{125} B^{1345} + A^{13} B^{124} + A^{134} B^{12} - A^{1345} B^{125} + A^{135} B^{1245} - A^{14} B^{123} - A^{145} B^{1235} - A^{15} B^{12345} + A^{2} B^{34} + A^{23} B^{4} + A^{234} B - A^{2345} B^{5} + A^{235} B^{45} - A^{24} B^{3} - A^{245} B^{35} - A^{25} B^{345} - A^{3} B^{24} + A^{34} B^{2} + A^{345} B^{25} + A^{35} B^{245} + A^{4} B^{23} - A^{45} B^{235} + A^{5} B^{2345}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{235} + A^{1} B^{1235} - A^{12} B^{135} + A^{123} B^{15} - A^{1234} B^{145} - A^{12345} B^{14} - A^{1235} B^{1} - A^{124} B^{1345} + A^{1245} B^{134} - A^{125} B^{13} + A^{13} B^{125} + A^{134} B^{1245} - A^{1345} B^{124} + A^{135} B^{12} - A^{14} B^{12345} - A^{145} B^{1234} - A^{15} B^{123} + A^{2} B^{35} + A^{23} B^{5} + A^{234} B^{45} - A^{2345} B^{4} + A^{235} B - A^{24} B^{345} - A^{245} B^{34} - A^{25} B^{3} - A^{3} B^{25} + A^{34} B^{245} + A^{345} B^{24} + A^{35} B^{2} + A^{4} B^{2345} - A^{45} B^{234} + A^{5} B^{23}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{245} + A^{1} B^{1245} - A^{12} B^{145} + A^{123} B^{1345} + A^{1234} B^{135} + A^{12345} B^{13} - A^{1235} B^{134} + A^{124} B^{15} - A^{1245} B^{1} - A^{125} B^{14} + A^{13} B^{12345} - A^{134} B^{1235} + A^{1345} B^{123} + A^{135} B^{1234} + A^{14} B^{125} + A^{145} B^{12} - A^{15} B^{124} + A^{2} B^{45} + A^{23} B^{345} - A^{234} B^{35} + A^{2345} B^{3} + A^{235} B^{34} + A^{24} B^{5} + A^{245} B - A^{25} B^{4} - A^{3} B^{2345} - A^{34} B^{235} - A^{345} B^{23} + A^{35} B^{234} - A^{4} B^{25} + A^{45} B^{2} + A^{5} B^{24}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{345} + A^{1} B^{1345} - A^{12} B^{12345} - A^{123} B^{1245} - A^{1234} B^{125} - A^{12345} B^{12} + A^{1235} B^{124} + A^{124} B^{1235} - A^{1245} B^{123} - A^{125} B^{1234} - A^{13} B^{145} + A^{134} B^{15} - A^{1345} B^{1} - A^{135} B^{14} + A^{14} B^{135} + A^{145} B^{13} - A^{15} B^{134} + A^{2} B^{2345} - A^{23} B^{245} + A^{234} B^{25} - A^{2345} B^{2} - A^{235} B^{24} + A^{24} B^{235} + A^{245} B^{23} - A^{25} B^{234} + A^{3} B^{45} + A^{34} B^{5} + A^{345} B - A^{35} B^{4} - A^{4} B^{35} + A^{45} B^{3} + A^{5} B^{34}\\right ) \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{1234} + A^{1} B^{234} + A^{12} B^{34} + A^{123} B^{4} + A^{1234} B - A^{12345} B^{5} + A^{1235} B^{45} - A^{124} B^{3} - A^{1245} B^{35} - A^{125} B^{345} - A^{13} B^{24} + A^{134} B^{2} + A^{1345} B^{25} + A^{135} B^{245} + A^{14} B^{23} - A^{145} B^{235} + A^{15} B^{2345} - A^{2} B^{134} + A^{23} B^{14} - A^{234} B^{1} - A^{2345} B^{15} - A^{235} B^{145} - A^{24} B^{13} + A^{245} B^{135} - A^{25} B^{1345} + A^{3} B^{124} + A^{34} B^{12} - A^{345} B^{125} + A^{35} B^{1245} - A^{4} B^{123} - A^{45} B^{1235} - A^{5} B^{12345}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4} + \\left ( A B^{1235} + A^{1} B^{235} + A^{12} B^{35} + A^{123} B^{5} + A^{1234} B^{45} - A^{12345} B^{4} + A^{1235} B - A^{124} B^{345} - A^{1245} B^{34} - A^{125} B^{3} - A^{13} B^{25} + A^{134} B^{245} + A^{1345} B^{24} + A^{135} B^{2} + A^{14} B^{2345} - A^{145} B^{234} + A^{15} B^{23} - A^{2} B^{135} + A^{23} B^{15} - A^{234} B^{145} - A^{2345} B^{14} - A^{235} B^{1} - A^{24} B^{1345} + A^{245} B^{134} - A^{25} B^{13} + A^{3} B^{125} + A^{34} B^{1245} - A^{345} B^{124} + A^{35} B^{12} - A^{4} B^{12345} - A^{45} B^{1234} - A^{5} B^{123}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{1245} + A^{1} B^{245} + A^{12} B^{45} + A^{123} B^{345} - A^{1234} B^{35} + A^{12345} B^{3} + A^{1235} B^{34} + A^{124} B^{5} + A^{1245} B - A^{125} B^{4} - A^{13} B^{2345} - A^{134} B^{235} - A^{1345} B^{23} + A^{135} B^{234} - A^{14} B^{25} + A^{145} B^{2} + A^{15} B^{24} - A^{2} B^{145} + A^{23} B^{1345} + A^{234} B^{135} + A^{2345} B^{13} - A^{235} B^{134} + A^{24} B^{15} - A^{245} B^{1} - A^{25} B^{14} + A^{3} B^{12345} - A^{34} B^{1235} + A^{345} B^{123} + A^{35} B^{1234} + A^{4} B^{125} + A^{45} B^{12} - A^{5} B^{124}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{1345} + A^{1} B^{345} + A^{12} B^{2345} - A^{123} B^{245} + A^{1234} B^{25} - A^{12345} B^{2} - A^{1235} B^{24} + A^{124} B^{235} + A^{1245} B^{23} - A^{125} B^{234} + A^{13} B^{45} + A^{134} B^{5} + A^{1345} B - A^{135} B^{4} - A^{14} B^{35} + A^{145} B^{3} + A^{15} B^{34} - A^{2} B^{12345} - A^{23} B^{1245} - A^{234} B^{125} - A^{2345} B^{12} + A^{235} B^{124} + A^{24} B^{1235} - A^{245} B^{123} - A^{25} B^{1234} - A^{3} B^{145} + A^{34} B^{15} - A^{345} B^{1} - A^{35} B^{14} + A^{4} B^{135} + A^{45} B^{13} - A^{5} B^{134}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{2345} + A^{1} B^{12345} - A^{12} B^{1345} + A^{123} B^{145} - A^{1234} B^{15} + A^{12345} B^{1} + A^{1235} B^{14} - A^{124} B^{135} - A^{1245} B^{13} + A^{125} B^{134} + A^{13} B^{1245} + A^{134} B^{125} + A^{1345} B^{12} - A^{135} B^{124} - A^{14} B^{1235} + A^{145} B^{123} + A^{15} B^{1234} + A^{2} B^{345} + A^{23} B^{45} + A^{234} B^{5} + A^{2345} B - A^{235} B^{4} - A^{24} B^{35} + A^{245} B^{3} + A^{25} B^{34} - A^{3} B^{245} + A^{34} B^{25} - A^{345} B^{2} - A^{35} B^{24} + A^{4} B^{235} + A^{45} B^{23} - A^{5} B^{234}\\right ) \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5} + \\left ( A B^{12345} + A^{1} B^{2345} + A^{12} B^{345} + A^{123} B^{45} + A^{1234} B^{5} + A^{12345} B - A^{1235} B^{4} - A^{124} B^{35} + A^{1245} B^{3} + A^{125} B^{34} - A^{13} B^{245} + A^{134} B^{25} - A^{1345} B^{2} - A^{135} B^{24} + A^{14} B^{235} + A^{145} B^{23} - A^{15} B^{234} - A^{2} B^{1345} + A^{23} B^{145} - A^{234} B^{15} + A^{2345} B^{1} + A^{235} B^{14} - A^{24} B^{135} - A^{245} B^{13} + A^{25} B^{134} + A^{3} B^{1245} + A^{34} B^{125} + A^{345} B^{12} - A^{35} B^{124} - A^{4} B^{1235} + A^{45} B^{123} + A^{5} B^{1234}\\right ) \\boldsymbol{e}_{1}\\wedge \\boldsymbol{e}_{2}\\wedge \\boldsymbol{e}_{3}\\wedge \\boldsymbol{e}_{4}\\wedge \\boldsymbol{e}_{5}\\end{align*}"
      ],
      "text/plain": [
       "A*B + A__1*B__1 - A__12*B__12 - A__123*B__123 + A__1234*B__1234 - A__12345*B__12345 - A__1235*B__1235 - A__124*B__124 - A__1245*B__1245 + A__125*B__125 - A__13*B__13 - A__134*B__134 - A__1345*B__1345 + A__135*B__135 - A__14*B__14 + A__145*B__145 + A__15*B__15 + A__2*B__2 - A__23*B__23 - A__234*B__234 - A__2345*B__2345 + A__235*B__235 - A__24*B__24 + A__245*B__245 + A__25*B__25 + A__3*B__3 - A__34*B__34 + A__345*B__345 + A__35*B__35 + A__4*B__4 + A__45*B__45 - A__5*B__5 + (A*B__1 + A__1*B + A__12*B__2 - A__123*B__23 - A__1234*B__234 - A__12345*B__2345 + A__1235*B__235 - A__124*B__24 + A__1245*B__245 + A__125*B__25 + A__13*B__3 - A__134*B__34 + A__1345*B__345 + A__135*B__35 + A__14*B__4 + A__145*B__45 - A__15*B__5 - A__2*B__12 - A__23*B__123 + A__234*B__1234 - A__2345*B__12345 - A__235*B__1235 - A__24*B__124 - A__245*B__1245 + A__25*B__125 - A__3*B__13 - A__34*B__134 - A__345*B__1345 + A__35*B__135 - A__4*B__14 + A__45*B__145 + A__5*B__15)*e_1 + (A*B__2 + A__1*B__12 - A__12*B__1 + A__123*B__13 + A__1234*B__134 + A__12345*B__1345 - A__1235*B__135 + A__124*B__14 - A__1245*B__145 - A__125*B__15 + A__13*B__123 - A__134*B__1234 + A__1345*B__12345 + A__135*B__1235 + A__14*B__124 + A__145*B__1245 - A__15*B__125 + A__2*B + A__23*B__3 - A__234*B__34 + A__2345*B__345 + A__235*B__35 + A__24*B__4 + A__245*B__45 - A__25*B__5 - A__3*B__23 - A__34*B__234 - A__345*B__2345 + A__35*B__235 - A__4*B__24 + A__45*B__245 + A__5*B__25)*e_2 + (A*B__3 + A__1*B__13 - A__12*B__123 - A__123*B__12 - A__1234*B__124 - A__12345*B__1245 + A__1235*B__125 + A__124*B__1234 - A__1245*B__12345 - A__125*B__1235 - A__13*B__1 + A__134*B__14 - A__1345*B__145 - A__135*B__15 + A__14*B__134 + A__145*B__1345 - A__15*B__135 + A__2*B__23 - A__23*B__2 + A__234*B__24 - A__2345*B__245 - A__235*B__25 + A__24*B__234 + A__245*B__2345 - A__25*B__235 + A__3*B + A__34*B__4 + A__345*B__45 - A__35*B__5 - A__4*B__34 + A__45*B__345 + A__5*B__35)*e_3 + (A*B__4 + A__1*B__14 - A__12*B__124 - A__123*B__1234 + A__1234*B__123 + A__12345*B__1235 + A__1235*B__12345 - A__124*B__12 + A__1245*B__125 - A__125*B__1245 - A__13*B__134 - A__134*B__13 + A__1345*B__135 - A__135*B__1345 - A__14*B__1 - A__145*B__15 - A__15*B__145 + A__2*B__24 - A__23*B__234 - A__234*B__23 + A__2345*B__235 - A__235*B__2345 - A__24*B__2 - A__245*B__25 - A__25*B__245 + A__3*B__34 - A__34*B__3 - A__345*B__35 - A__35*B__345 + A__4*B - A__45*B__5 + A__5*B__45)*e_4 + (A*B__5 + A__1*B__15 - A__12*B__125 - A__123*B__1235 + A__1234*B__12345 + A__12345*B__1234 + A__1235*B__123 - A__124*B__1245 + A__1245*B__124 - A__125*B__12 - A__13*B__135 - A__134*B__1345 + A__1345*B__134 - A__135*B__13 - A__14*B__145 - A__145*B__14 - A__15*B__1 + A__2*B__25 - A__23*B__235 - A__234*B__2345 + A__2345*B__234 - A__235*B__23 - A__24*B__245 - A__245*B__24 - A__25*B__2 + A__3*B__35 - A__34*B__345 - A__345*B__34 - A__35*B__3 + A__4*B__45 - A__45*B__4 + A__5*B)*e_5 + (A*B__12 + A__1*B__2 + A__12*B + A__123*B__3 - A__1234*B__34 + A__12345*B__345 + A__1235*B__35 + A__124*B__4 + A__1245*B__45 - A__125*B__5 - A__13*B__23 - A__134*B__234 - A__1345*B__2345 + A__135*B__235 - A__14*B__24 + A__145*B__245 + A__15*B__25 - A__2*B__1 + A__23*B__13 + A__234*B__134 + A__2345*B__1345 - A__235*B__135 + A__24*B__14 - A__245*B__145 - A__25*B__15 + A__3*B__123 - A__34*B__1234 + A__345*B__12345 + A__35*B__1235 + A__4*B__124 + A__45*B__1245 - A__5*B__125)*e_1^e_2 + (A*B__13 + A__1*B__3 + A__12*B__23 - A__123*B__2 + A__1234*B__24 - A__12345*B__245 - A__1235*B__25 + A__124*B__234 + A__1245*B__2345 - A__125*B__235 + A__13*B + A__134*B__4 + A__1345*B__45 - A__135*B__5 - A__14*B__34 + A__145*B__345 + A__15*B__35 - A__2*B__123 - A__23*B__12 - A__234*B__124 - A__2345*B__1245 + A__235*B__125 + A__24*B__1234 - A__245*B__12345 - A__25*B__1235 - A__3*B__1 + A__34*B__14 - A__345*B__145 - A__35*B__15 + A__4*B__134 + A__45*B__1345 - A__5*B__135)*e_1^e_3 + (A*B__14 + A__1*B__4 + A__12*B__24 - A__123*B__234 - A__1234*B__23 + A__12345*B__235 - A__1235*B__2345 - A__124*B__2 - A__1245*B__25 - A__125*B__245 + A__13*B__34 - A__134*B__3 - A__1345*B__35 - A__135*B__345 + A__14*B - A__145*B__5 + A__15*B__45 - A__2*B__124 - A__23*B__1234 + A__234*B__123 + A__2345*B__1235 + A__235*B__12345 - A__24*B__12 + A__245*B__125 - A__25*B__1245 - A__3*B__134 - A__34*B__13 + A__345*B__135 - A__35*B__1345 - A__4*B__1 - A__45*B__15 - A__5*B__145)*e_1^e_4 + (A*B__15 + A__1*B__5 + A__12*B__25 - A__123*B__235 - A__1234*B__2345 + A__12345*B__234 - A__1235*B__23 - A__124*B__245 - A__1245*B__24 - A__125*B__2 + A__13*B__35 - A__134*B__345 - A__1345*B__34 - A__135*B__3 + A__14*B__45 - A__145*B__4 + A__15*B - A__2*B__125 - A__23*B__1235 + A__234*B__12345 + A__2345*B__1234 + A__235*B__123 - A__24*B__1245 + A__245*B__124 - A__25*B__12 - A__3*B__135 - A__34*B__1345 + A__345*B__134 - A__35*B__13 - A__4*B__145 - A__45*B__14 - A__5*B__1)*e_1^e_5 + (A*B__23 + A__1*B__123 - A__12*B__13 + A__123*B__1 - A__1234*B__14 + A__12345*B__145 + A__1235*B__15 - A__124*B__134 - A__1245*B__1345 + A__125*B__135 + A__13*B__12 + A__134*B__124 + A__1345*B__1245 - A__135*B__125 - A__14*B__1234 + A__145*B__12345 + A__15*B__1235 + A__2*B__3 + A__23*B + A__234*B__4 + A__2345*B__45 - A__235*B__5 - A__24*B__34 + A__245*B__345 + A__25*B__35 - A__3*B__2 + A__34*B__24 - A__345*B__245 - A__35*B__25 + A__4*B__234 + A__45*B__2345 - A__5*B__235)*e_2^e_3 + (A*B__24 + A__1*B__124 - A__12*B__14 + A__123*B__134 + A__1234*B__13 - A__12345*B__135 + A__1235*B__1345 + A__124*B__1 + A__1245*B__15 + A__125*B__145 + A__13*B__1234 - A__134*B__123 - A__1345*B__1235 - A__135*B__12345 + A__14*B__12 - A__145*B__125 + A__15*B__1245 + A__2*B__4 + A__23*B__34 - A__234*B__3 - A__2345*B__35 - A__235*B__345 + A__24*B - A__245*B__5 + A__25*B__45 - A__3*B__234 - A__34*B__23 + A__345*B__235 - A__35*B__2345 - A__4*B__2 - A__45*B__25 - A__5*B__245)*e_2^e_4 + (A*B__25 + A__1*B__125 - A__12*B__15 + A__123*B__135 + A__1234*B__1345 - A__12345*B__134 + A__1235*B__13 + A__124*B__145 + A__1245*B__14 + A__125*B__1 + A__13*B__1235 - A__134*B__12345 - A__1345*B__1234 - A__135*B__123 + A__14*B__1245 - A__145*B__124 + A__15*B__12 + A__2*B__5 + A__23*B__35 - A__234*B__345 - A__2345*B__34 - A__235*B__3 + A__24*B__45 - A__245*B__4 + A__25*B - A__3*B__235 - A__34*B__2345 + A__345*B__234 - A__35*B__23 - A__4*B__245 - A__45*B__24 - A__5*B__2)*e_2^e_5 + (A*B__34 + A__1*B__134 - A__12*B__1234 - A__123*B__124 - A__1234*B__12 + A__12345*B__125 - A__1235*B__1245 + A__124*B__123 + A__1245*B__1235 + A__125*B__12345 - A__13*B__14 + A__134*B__1 + A__1345*B__15 + A__135*B__145 + A__14*B__13 - A__145*B__135 + A__15*B__1345 + A__2*B__234 - A__23*B__24 + A__234*B__2 + A__2345*B__25 + A__235*B__245 + A__24*B__23 - A__245*B__235 + A__25*B__2345 + A__3*B__4 + A__34*B - A__345*B__5 + A__35*B__45 - A__4*B__3 - A__45*B__35 - A__5*B__345)*e_3^e_4 + (A*B__35 + A__1*B__135 - A__12*B__1235 - A__123*B__125 - A__1234*B__1245 + A__12345*B__124 - A__1235*B__12 + A__124*B__12345 + A__1245*B__1234 + A__125*B__123 - A__13*B__15 + A__134*B__145 + A__1345*B__14 + A__135*B__1 + A__14*B__1345 - A__145*B__134 + A__15*B__13 + A__2*B__235 - A__23*B__25 + A__234*B__245 + A__2345*B__24 + A__235*B__2 + A__24*B__2345 - A__245*B__234 + A__25*B__23 + A__3*B__5 + A__34*B__45 - A__345*B__4 + A__35*B - A__4*B__345 - A__45*B__34 - A__5*B__3)*e_3^e_5 + (A*B__45 + A__1*B__145 - A__12*B__1245 - A__123*B__12345 + A__1234*B__1235 - A__12345*B__123 - A__1235*B__1234 - A__124*B__125 - A__1245*B__12 + A__125*B__124 - A__13*B__1345 - A__134*B__135 - A__1345*B__13 + A__135*B__134 - A__14*B__15 + A__145*B__1 + A__15*B__14 + A__2*B__245 - A__23*B__2345 - A__234*B__235 - A__2345*B__23 + A__235*B__234 - A__24*B__25 + A__245*B__2 + A__25*B__24 + A__3*B__345 - A__34*B__35 + A__345*B__3 + A__35*B__34 + A__4*B__5 + A__45*B - A__5*B__4)*e_4^e_5 + (A*B__123 + A__1*B__23 + A__12*B__3 + A__123*B + A__1234*B__4 + A__12345*B__45 - A__1235*B__5 - A__124*B__34 + A__1245*B__345 + A__125*B__35 - A__13*B__2 + A__134*B__24 - A__1345*B__245 - A__135*B__25 + A__14*B__234 + A__145*B__2345 - A__15*B__235 - A__2*B__13 + A__23*B__1 - A__234*B__14 + A__2345*B__145 + A__235*B__15 - A__24*B__134 - A__245*B__1345 + A__25*B__135 + A__3*B__12 + A__34*B__124 + A__345*B__1245 - A__35*B__125 - A__4*B__1234 + A__45*B__12345 + A__5*B__1235)*e_1^e_2^e_3 + (A*B__124 + A__1*B__24 + A__12*B__4 + A__123*B__34 - A__1234*B__3 - A__12345*B__35 - A__1235*B__345 + A__124*B - A__1245*B__5 + A__125*B__45 - A__13*B__234 - A__134*B__23 + A__1345*B__235 - A__135*B__2345 - A__14*B__2 - A__145*B__25 - A__15*B__245 - A__2*B__14 + A__23*B__134 + A__234*B__13 - A__2345*B__135 + A__235*B__1345 + A__24*B__1 + A__245*B__15 + A__25*B__145 + A__3*B__1234 - A__34*B__123 - A__345*B__1235 - A__35*B__12345 + A__4*B__12 - A__45*B__125 + A__5*B__1245)*e_1^e_2^e_4 + (A*B__125 + A__1*B__25 + A__12*B__5 + A__123*B__35 - A__1234*B__345 - A__12345*B__34 - A__1235*B__3 + A__124*B__45 - A__1245*B__4 + A__125*B - A__13*B__235 - A__134*B__2345 + A__1345*B__234 - A__135*B__23 - A__14*B__245 - A__145*B__24 - A__15*B__2 - A__2*B__15 + A__23*B__135 + A__234*B__1345 - A__2345*B__134 + A__235*B__13 + A__24*B__145 + A__245*B__14 + A__25*B__1 + A__3*B__1235 - A__34*B__12345 - A__345*B__1234 - A__35*B__123 + A__4*B__1245 - A__45*B__124 + A__5*B__12)*e_1^e_2^e_5 + (A*B__134 + A__1*B__34 + A__12*B__234 - A__123*B__24 + A__1234*B__2 + A__12345*B__25 + A__1235*B__245 + A__124*B__23 - A__1245*B__235 + A__125*B__2345 + A__13*B__4 + A__134*B - A__1345*B__5 + A__135*B__45 - A__14*B__3 - A__145*B__35 - A__15*B__345 - A__2*B__1234 - A__23*B__124 - A__234*B__12 + A__2345*B__125 - A__235*B__1245 + A__24*B__123 + A__245*B__1235 + A__25*B__12345 - A__3*B__14 + A__34*B__1 + A__345*B__15 + A__35*B__145 + A__4*B__13 - A__45*B__135 + A__5*B__1345)*e_1^e_3^e_4 + (A*B__135 + A__1*B__35 + A__12*B__235 - A__123*B__25 + A__1234*B__245 + A__12345*B__24 + A__1235*B__2 + A__124*B__2345 - A__1245*B__234 + A__125*B__23 + A__13*B__5 + A__134*B__45 - A__1345*B__4 + A__135*B - A__14*B__345 - A__145*B__34 - A__15*B__3 - A__2*B__1235 - A__23*B__125 - A__234*B__1245 + A__2345*B__124 - A__235*B__12 + A__24*B__12345 + A__245*B__1234 + A__25*B__123 - A__3*B__15 + A__34*B__145 + A__345*B__14 + A__35*B__1 + A__4*B__1345 - A__45*B__134 + A__5*B__13)*e_1^e_3^e_5 + (A*B__145 + A__1*B__45 + A__12*B__245 - A__123*B__2345 - A__1234*B__235 - A__12345*B__23 + A__1235*B__234 - A__124*B__25 + A__1245*B__2 + A__125*B__24 + A__13*B__345 - A__134*B__35 + A__1345*B__3 + A__135*B__34 + A__14*B__5 + A__145*B - A__15*B__4 - A__2*B__1245 - A__23*B__12345 + A__234*B__1235 - A__2345*B__123 - A__235*B__1234 - A__24*B__125 - A__245*B__12 + A__25*B__124 - A__3*B__1345 - A__34*B__135 - A__345*B__13 + A__35*B__134 - A__4*B__15 + A__45*B__1 + A__5*B__14)*e_1^e_4^e_5 + (A*B__234 + A__1*B__1234 - A__12*B__134 + A__123*B__14 - A__1234*B__1 - A__12345*B__15 - A__1235*B__145 - A__124*B__13 + A__1245*B__135 - A__125*B__1345 + A__13*B__124 + A__134*B__12 - A__1345*B__125 + A__135*B__1245 - A__14*B__123 - A__145*B__1235 - A__15*B__12345 + A__2*B__34 + A__23*B__4 + A__234*B - A__2345*B__5 + A__235*B__45 - A__24*B__3 - A__245*B__35 - A__25*B__345 - A__3*B__24 + A__34*B__2 + A__345*B__25 + A__35*B__245 + A__4*B__23 - A__45*B__235 + A__5*B__2345)*e_2^e_3^e_4 + (A*B__235 + A__1*B__1235 - A__12*B__135 + A__123*B__15 - A__1234*B__145 - A__12345*B__14 - A__1235*B__1 - A__124*B__1345 + A__1245*B__134 - A__125*B__13 + A__13*B__125 + A__134*B__1245 - A__1345*B__124 + A__135*B__12 - A__14*B__12345 - A__145*B__1234 - A__15*B__123 + A__2*B__35 + A__23*B__5 + A__234*B__45 - A__2345*B__4 + A__235*B - A__24*B__345 - A__245*B__34 - A__25*B__3 - A__3*B__25 + A__34*B__245 + A__345*B__24 + A__35*B__2 + A__4*B__2345 - A__45*B__234 + A__5*B__23)*e_2^e_3^e_5 + (A*B__245 + A__1*B__1245 - A__12*B__145 + A__123*B__1345 + A__1234*B__135 + A__12345*B__13 - A__1235*B__134 + A__124*B__15 - A__1245*B__1 - A__125*B__14 + A__13*B__12345 - A__134*B__1235 + A__1345*B__123 + A__135*B__1234 + A__14*B__125 + A__145*B__12 - A__15*B__124 + A__2*B__45 + A__23*B__345 - A__234*B__35 + A__2345*B__3 + A__235*B__34 + A__24*B__5 + A__245*B - A__25*B__4 - A__3*B__2345 - A__34*B__235 - A__345*B__23 + A__35*B__234 - A__4*B__25 + A__45*B__2 + A__5*B__24)*e_2^e_4^e_5 + (A*B__345 + A__1*B__1345 - A__12*B__12345 - A__123*B__1245 - A__1234*B__125 - A__12345*B__12 + A__1235*B__124 + A__124*B__1235 - A__1245*B__123 - A__125*B__1234 - A__13*B__145 + A__134*B__15 - A__1345*B__1 - A__135*B__14 + A__14*B__135 + A__145*B__13 - A__15*B__134 + A__2*B__2345 - A__23*B__245 + A__234*B__25 - A__2345*B__2 - A__235*B__24 + A__24*B__235 + A__245*B__23 - A__25*B__234 + A__3*B__45 + A__34*B__5 + A__345*B - A__35*B__4 - A__4*B__35 + A__45*B__3 + A__5*B__34)*e_3^e_4^e_5 + (A*B__1234 + A__1*B__234 + A__12*B__34 + A__123*B__4 + A__1234*B - A__12345*B__5 + A__1235*B__45 - A__124*B__3 - A__1245*B__35 - A__125*B__345 - A__13*B__24 + A__134*B__2 + A__1345*B__25 + A__135*B__245 + A__14*B__23 - A__145*B__235 + A__15*B__2345 - A__2*B__134 + A__23*B__14 - A__234*B__1 - A__2345*B__15 - A__235*B__145 - A__24*B__13 + A__245*B__135 - A__25*B__1345 + A__3*B__124 + A__34*B__12 - A__345*B__125 + A__35*B__1245 - A__4*B__123 - A__45*B__1235 - A__5*B__12345)*e_1^e_2^e_3^e_4 + (A*B__1235 + A__1*B__235 + A__12*B__35 + A__123*B__5 + A__1234*B__45 - A__12345*B__4 + A__1235*B - A__124*B__345 - A__1245*B__34 - A__125*B__3 - A__13*B__25 + A__134*B__245 + A__1345*B__24 + A__135*B__2 + A__14*B__2345 - A__145*B__234 + A__15*B__23 - A__2*B__135 + A__23*B__15 - A__234*B__145 - A__2345*B__14 - A__235*B__1 - A__24*B__1345 + A__245*B__134 - A__25*B__13 + A__3*B__125 + A__34*B__1245 - A__345*B__124 + A__35*B__12 - A__4*B__12345 - A__45*B__1234 - A__5*B__123)*e_1^e_2^e_3^e_5 + (A*B__1245 + A__1*B__245 + A__12*B__45 + A__123*B__345 - A__1234*B__35 + A__12345*B__3 + A__1235*B__34 + A__124*B__5 + A__1245*B - A__125*B__4 - A__13*B__2345 - A__134*B__235 - A__1345*B__23 + A__135*B__234 - A__14*B__25 + A__145*B__2 + A__15*B__24 - A__2*B__145 + A__23*B__1345 + A__234*B__135 + A__2345*B__13 - A__235*B__134 + A__24*B__15 - A__245*B__1 - A__25*B__14 + A__3*B__12345 - A__34*B__1235 + A__345*B__123 + A__35*B__1234 + A__4*B__125 + A__45*B__12 - A__5*B__124)*e_1^e_2^e_4^e_5 + (A*B__1345 + A__1*B__345 + A__12*B__2345 - A__123*B__245 + A__1234*B__25 - A__12345*B__2 - A__1235*B__24 + A__124*B__235 + A__1245*B__23 - A__125*B__234 + A__13*B__45 + A__134*B__5 + A__1345*B - A__135*B__4 - A__14*B__35 + A__145*B__3 + A__15*B__34 - A__2*B__12345 - A__23*B__1245 - A__234*B__125 - A__2345*B__12 + A__235*B__124 + A__24*B__1235 - A__245*B__123 - A__25*B__1234 - A__3*B__145 + A__34*B__15 - A__345*B__1 - A__35*B__14 + A__4*B__135 + A__45*B__13 - A__5*B__134)*e_1^e_3^e_4^e_5 + (A*B__2345 + A__1*B__12345 - A__12*B__1345 + A__123*B__145 - A__1234*B__15 + A__12345*B__1 + A__1235*B__14 - A__124*B__135 - A__1245*B__13 + A__125*B__134 + A__13*B__1245 + A__134*B__125 + A__1345*B__12 - A__135*B__124 - A__14*B__1235 + A__145*B__123 + A__15*B__1234 + A__2*B__345 + A__23*B__45 + A__234*B__5 + A__2345*B - A__235*B__4 - A__24*B__35 + A__245*B__3 + A__25*B__34 - A__3*B__245 + A__34*B__25 - A__345*B__2 - A__35*B__24 + A__4*B__235 + A__45*B__23 - A__5*B__234)*e_2^e_3^e_4^e_5 + (A*B__12345 + A__1*B__2345 + A__12*B__345 + A__123*B__45 + A__1234*B__5 + A__12345*B - A__1235*B__4 - A__124*B__35 + A__1245*B__3 + A__125*B__34 - A__13*B__245 + A__134*B__25 - A__1345*B__2 - A__135*B__24 + A__14*B__235 + A__145*B__23 - A__15*B__234 - A__2*B__1345 + A__23*B__145 - A__234*B__15 + A__2345*B__1 + A__235*B__14 - A__24*B__135 - A__245*B__13 + A__25*B__134 + A__3*B__1245 + A__34*B__125 + A__345*B__12 - A__35*B__124 - A__4*B__1235 + A__45*B__123 + A__5*B__1234)*e_1^e_2^e_3^e_4^e_5"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "@time test_geometric_product(CGA3D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "test_all (generic function with 1 method)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function test_all(V)\n",
    "    dimV = range(0, stop=V.n)\n",
    "    I = V.I()\n",
    "\n",
    "    α = V.mv(\"α\", \"scalar\")\n",
    "    β = V.mv(\"β\", \"scalar\")\n",
    "    γ = V.mv(\"γ\", \"scalar\")\n",
    "    λ = V.mv(\"λ\", \"scalar\")\n",
    "\n",
    "    u = V.mv(\"u\", \"vector\")\n",
    "    v = V.mv(\"v\", \"vector\")\n",
    "    w = V.mv(\"w\", \"vector\")\n",
    "\n",
    "    A = V.mv(\"A\", \"mv\")\n",
    "    B = V.mv(\"B\", \"mv\")\n",
    "    C = V.mv(\"C\", \"mv\")\n",
    "    D = V.mv(\"D\", \"mv\")\n",
    "\n",
    "    R = V.mv(\"R\", \"spinor\")\n",
    "    \n",
    "    # Precalculte AB and BA\n",
    "    AB = A * B\n",
    "    BA = B * A\n",
    "\n",
    "    # The following tests verified implementation correctness per definition\n",
    "\n",
    "    @test u ⋅ v == u | v == (u < v) == (u > v) == u ⨼ v == u ⨽ v == u ⊙ v\n",
    "    @test u ∧ v == u ⊠ v\n",
    "    @test v ⨼ B == (v < B)\n",
    "    @test v ⨽ B == (v > B)\n",
    "    if V ∉ [PGA3D, CGA3D] # too slow\n",
    "        @test A ⊙ B == A << B == (AB + BA) / 2\n",
    "        # @test A ×̄ B == A ⊙ B\n",
    "        @test A ⊠ B == A >> B == (AB - BA) / 2\n",
    "        @test A ⊛ B == A % B\n",
    "    end\n",
    "\n",
    "    @test abs(v) == norm(v) == v.norm()\n",
    "    if V ∉ [Spacetime, PGA2D, PGA3D, CGA2D, CGA3D]\n",
    "        @test abs(R) == norm(R) == R.norm()\n",
    "    end\n",
    "\n",
    "    @test ~A == A[:~] == rev(A) == A.rev()\n",
    "\n",
    "    if V ∉ [Dual, PGA2D, PGA3D, CGA2D, CGA3D]\n",
    "        @test A' == dual(A) == A.dual() == adjoint(A) == A * I # Ga.dual_mode_value is default to \"I+\"\n",
    "        @test (v)⁻¹ == v[:⁻¹] == v^-1 == inv(v) == v.inv()\n",
    "        @test v^-2 == (v^2).inv()\n",
    "    end\n",
    "\n",
    "    @test (A)ˣ == A[:*] == involute(A) == (A)₊ - (A)₋ == A[:+] - A[:-] == A.even() - A.odd()\n",
    "    @test (A)ǂ == A[:ǂ] == conj(A) == involute(A).rev()   \n",
    "\n",
    "    if V ∉ [Spacetime, PGA2D, PGA3D, CGA2D, CGA3D]\n",
    "        @test R^-2 == (R^2).inv()\n",
    "        @test (R)⁻¹ == R[:⁻¹] == R^-1 == inv(R) == R.inv()\n",
    "        @test ((R)⁻¹)ˣ == ((R)ˣ)⁻¹\n",
    "        @test ((R)⁻¹)ǂ == ((R)ǂ)⁻¹\n",
    "    end\n",
    "\n",
    "    if V ∈ [Cl2, Cl3]\n",
    "        @test (v)⁻¹ == (~v) / norm(v)^2 == v / v^2 \n",
    "        @test (R)⁻¹ == (~R) / norm(R)^2 == R / R^2\n",
    "    end\n",
    "\n",
    "    @test v^0 == 1\n",
    "    @test v^2 == v*v\n",
    "\n",
    "    @test ((A)ˣ)ˣ == ~(~A) == A[:~][:~] == ((A)ǂ)ǂ == A\n",
    "    @test ~((A)ˣ) == (~A)ˣ\n",
    "\n",
    "    if V ∉ [Dual]\n",
    "        @test proj(u, v) == v.project_in_blade(u)\n",
    "        @test refl(u, v) == v.reflect_in_blade(u)\n",
    "    end\n",
    "\n",
    "    if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "        @test rot(u ∧ v, A) == A.rotate_multivector(u ∧ v)\n",
    "        @test exp(u ∧ v) == (u ∧ v).exp()\n",
    "    end\n",
    "\n",
    "    @test typeof(scalar(A)) == Sym\n",
    "    @test typeof(A[0]) == Mv\n",
    "    @test scalar(A) == A.scalar() == A[0].obj\n",
    "    @test (A)₊ == A[:+] == even(A) == A.even()\n",
    "    @test (A)₋ == A[:-] == odd(A) == A.odd()\n",
    "\n",
    "    for r ∈ dimV\n",
    "        A[r] == A.grade(r) == A.get_grade(r)\n",
    "    end\n",
    "\n",
    "    # The following tests verified many identities in Linear Algebra\n",
    "\n",
    "    @test v + w == w + v\n",
    "    @test (u + v) + w == u + (v + w)\n",
    "    @test v + 0 == v\n",
    "    @test 0 * v == 0\n",
    "    @test 1 * v == v\n",
    "    @test α * (β * v) == (α * β) * v\n",
    "    @test α * (v + w) == α * v + α * w\n",
    "    @test (α + β) * v == α * v + β * v\n",
    "    @test v + (-1) * v == 0\n",
    "    @test -v == -1 * v\n",
    "\n",
    "    𝑶 = vector(V, fill(0, V.n))\n",
    "    @test α * 𝑶 == 𝑶\n",
    "    @test (-α) * v == α * (-v) == -α * v\n",
    "\n",
    "    # The following tests verified many identities in https://arxiv.org/abs/1205.5935\n",
    "\n",
    "    @test v * v == (v * v).scalar()\n",
    "    @test v * B == v ⋅ B + v ∧ B == v ⨼ B + v ∧ B\n",
    "\n",
    "    @test u ∧ (v + λ * u) == u ∧ v\n",
    "\n",
    "    @test v == v[1]\n",
    "    if V.n >= 2\n",
    "        G2 = V.mv(\"G2\", \"grade\", 2)\n",
    "        @test G2 == G2[2]\n",
    "    end\n",
    "\n",
    "    for r ∈ dimV\n",
    "        @test (A + B)[r] == A[r] + B[r]\n",
    "        @test (λ * A)[r] == (A * λ)[r] == λ * A[r]\n",
    "\n",
    "        Ar = A[r]\n",
    "\n",
    "        @test v ⨼ Ar == (v * Ar - (-1)^r * Ar * v) / 2\n",
    "        @test Ar ⨽ v == (Ar * v - (-1)^r * v * Ar) / 2 == (-1)^(r-1) * (v ⨼ Ar)\n",
    "        @test v ∧ Ar == (v * Ar + (-1)^r * Ar * v) / 2\n",
    "        @test Ar ∧ v == (Ar * v + (-1)^r * v * Ar) / 2 == (-1)^r * (v ∧ Ar)\n",
    "\n",
    "        @test v ⨼ Ar == (v * Ar)[r-1]\n",
    "        @test v ∧ Ar == (v * Ar)[r+1]\n",
    "        @test Ar ⨽ v == (Ar * v)[r-1]\n",
    "        @test Ar ∧ v == (Ar * v)[r+1]\n",
    "        @test v * Ar == v ⨼ Ar + v ∧ Ar\n",
    "        @test Ar * v == Ar ⨽ v + Ar ∧ v\n",
    "\n",
    "        Br = B[r]\n",
    "        Ar ⨼ Br == Ar ⨽ Br == (Ar * Br).scalar()\n",
    "\n",
    "        for s ∈ dimV\n",
    "            @test A[r][s] == (if r == s; A[r] else 0 end)\n",
    "\n",
    "            Bs = B[s]\n",
    "            ArBs = Ar * Bs\n",
    "\n",
    "            @test ArBs == sum([ArBs[abs(r - s) + 2j] for j=0:min(r, s)])                      # A.4.1\n",
    "            @test Ar ⨼ Bs == (-1)^(r * (s - 1)) * Bs ⨽ Ar                                    # A.4.10\n",
    "            @test Ar ∧ Bs == (-1)^(r * s) * Bs ∧ Ar                                          # A.4.11\n",
    "\n",
    "            for j ∈ dimV\n",
    "                @test ArBs[r + s - 2j] == (-1)^(r * s - j) * (B[s] * A[r])[r + s - 2j]        # A.4.2\n",
    "            end\n",
    "\n",
    "            if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "                @test v ⨼ ArBs == (v * ArBs - (-1)^(r+s) * ArBs * v)/2 ==\n",
    "                    (v ⨼ Ar) * Bs + (-1)^r * Ar * (v ⨼ Bs) == \n",
    "                    (v ∧ Ar) * Bs - (-1)^r * Ar * (v ∧ Bs)\n",
    "                @test v ∧ ArBs == (v * ArBs + (-1)^(r+s) * ArBs * v)/2 ==\n",
    "                    (v ∧ Ar) * Bs - (-1)^r * Ar * (v ⨼ Bs) ==\n",
    "                    (v ⨼ Ar) * Bs + (-1)^r * Ar * (v ∧ Bs)\n",
    "            end\n",
    "            \n",
    "            @test v ⨼ (Ar ∧ Bs) == (v ⨼ Ar) ∧ Bs + (-1)^r * Ar ∧ (v ⨼ Bs)\n",
    "            @test v ∧ (Ar ⨽ Bs) == (v ∧ Ar) ⨽ Bs - (-1)^r * Ar ⨽ (v ⨼ Bs)\n",
    "            @test v ∧ (Ar ⨼ Bs) == (v ⨼ Ar) ⨼ Bs + (-1)^r * Ar ⨼ (v ∧ Bs)\n",
    "\n",
    "            if r > s\n",
    "                @test Ar ⨼ Bs == Bs ⨽ Ar == 0\n",
    "            end\n",
    "\n",
    "            if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "                for t ∈ dimV\n",
    "                    Ct = C[t]\n",
    "\n",
    "                    Ar ∧ (Bs ∧ Ct) == (Ar * Bs * Ct)[r + s + t]\n",
    "                end\n",
    "            end\n",
    "        end\n",
    "    end\n",
    "\n",
    "    @test A == sum([A[r] for r ∈ dimV])\n",
    "    @test A[-3] == 0\n",
    "\n",
    "    @test v ⨼ A == (v * A - (A)ˣ * v)/2                                                      # A.4.13\n",
    "    @test v ∧ A == (v * A + (A)ˣ * v)/2                                                      # A.4.14\n",
    "    @test A ⨽ v == - v ⨼ (A)ˣ                                                                # A.4.15\n",
    "    @test A ∧ v == v ∧ (A)ˣ                                                                  # A.4.16\n",
    "\n",
    "    if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "        @test v ⨼ (AB) == (v ⨼ A) * B + (A)ˣ * (v ⨼ B) == (v ∧ A) * B - (A)ˣ * (v ∧ B)       # A.4.18-19\n",
    "        @test v ∧ (AB) == (v ∧ A) * B - (A)ˣ * (v ⨼ B) == (v ⨼ A) * B + (A)ˣ * (v ∧ B)       # A.4.20-21\n",
    "    end\n",
    "    \n",
    "    @test v ⨼ (A ∧ B) == (v ⨼ A) ∧ B + (A)ˣ ∧ (v ⨼ B)                                       # A.4.22\n",
    "    @test v ∧ (A ⨽ B) == (v ∧ A) ⨽ B - (A)ˣ ⨽ (v ⨼ B)                                       # A.4.23\n",
    "    @test v ∧ (A ⨼ B) == (v ⨼ A) ⨼ B + (A)ˣ ⨼ (v ∧ B)                                       # A.4.24\n",
    "\n",
    "    @test v ⨼ A[:+] == - (A[:+] ⨽ v)\n",
    "    @test v ⨼ A[:-] == A[:-] ⨽ v\n",
    "    @test v ∧ A[:+] == A[:+] ∧ v\n",
    "    @test v ∧ A[:-] == - (A[:-] ∧ v)\n",
    "\n",
    "    if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "        @test (AB).scalar() == (BA).scalar() == (~A * ~B).scalar() == \n",
    "            ((A)ˣ * (B)ˣ).scalar() == ((A)ǂ * (B)ǂ).scalar()                                      # A.4.3-6\n",
    "    end\n",
    "\n",
    "    @test A ⨼ B == sum([sum([(A[r] * B[s])[s - r] for r ∈ dimV]) for s ∈ dimV])             # A.4.7\n",
    "    @test A ⨽ B == sum([sum([(A[r] * B[s])[r - s] for r ∈ dimV]) for s ∈ dimV])             # A.4.8\n",
    "    @test A ∧ B == sum([sum([(A[r] * B[s])[r + s] for r ∈ dimV]) for s ∈ dimV])             # A.4.9\n",
    "\n",
    "    @test (A ∧ B) ∧ C == A ∧ (B ∧ C) == A ∧ B ∧ C                                           # A.4.28\n",
    "    @test A ⨼ (B ⨽ C) == (A ⨼ B) ⨽ C                                                        # A.4.29\n",
    "    @test A ⨼ (B ⨼ C) == (A ∧ B) ⨼ C                                                        # A.4.30\n",
    "    @test A ⨽ (B ∧ C) == (A ⨽ B) ⨽ C                                                        # A.4.31\n",
    "    @test (A ∧ B) ⨼ C == A ⨼ (B ⨼ C)\n",
    "\n",
    "    @test u ∧ A ∧ v == - v ∧ A ∧ u                                                           # A.4.17\n",
    "\n",
    "    if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "        @test AB == A ⊠ B + A ⊙ B\n",
    "        @test A ⊙ B == B ⊙ A\n",
    "        @test A ⊠ B == - B ⊠ A\n",
    "\n",
    "        @test A ⊛ B == B ⊛ A\n",
    "        \n",
    "        @test A ⊛ B == ~A ⊛ ~B == A.rev() ⊛ B.rev()\n",
    "        @test A ⊛ (B * C) == (~B * A) ⊛ C\n",
    "        @test A ⊛ (B ⨽ C) == (~B ⨽ A) ⊛ C\n",
    "        @test A ⊛ (B ⨼ C) == (~B ∧ A) ⊛ C\n",
    "        @test A ⊛ (B ∧ C) == (~B ⨼ A) ⊛ C\n",
    "    end\n",
    "    \n",
    "    if V ∉ [Spacetime, ℂ, ℍ, Dual, PGA2D, PGA3D, CGA2D, CGA3D]\n",
    "        @test A ⊛ B == A' ⊛ B' == A.dual() ⊛ B.dual()\n",
    "    end \n",
    "\n",
    "    if V ∉ [PGA2D, PGA3D, CGA2D, CGA3D] # too slow\n",
    "        @test AB ⋅ C ∧ D == ((AB) ⋅ C) ∧ D\n",
    "    end\n",
    "\n",
    "    if V ∉ [Dual, PGA2D, PGA3D, CGA2D, CGA3D]\n",
    "        @test u.dual() == u * V.I()\n",
    "        @test proj(u, v) == (v ⋅ u) / u == (v ⨼ u) ⨼ u.inv()\n",
    "        @test proj(w, v) + proj(w, u) == proj(w, u + v)\n",
    "    end\n",
    "\n",
    "    if V == Cl3\n",
    "        @test u × v == -I * (u ∧ v)\n",
    "        @test_throws PyCall.PyError A × B\n",
    "\n",
    "        Vr = u ∧ v\n",
    "        @test proj(Vr, B) == B ⨼ Vr * (Vr)⁻¹ == (B ⨼ Vr) ⨼ (Vr)⁻¹                               # A.4.34\n",
    "        # TODO this is failing for now\n",
    "        @test_broken refl(Vr, B) == B ∧ Vr * (Vr)⁻¹ == (B ∧ Vr) ⨽ (Vr)⁻¹                               # A.4.35\n",
    "\n",
    "        # The following tests verified interoperability with numeric and symbolic numbers\n",
    "        (ex, ey, ez) = V.mv()\n",
    "\n",
    "        uu = vector(V, [1, 2, 3])\n",
    "        vv = vector(V, [4, 5, 6])\n",
    "        ww = vector(V, [5, 6, 7])\n",
    "\n",
    "        @test uu + vv == 5 * ex + 7 * ey + 9 * ez\n",
    "        @test 7 * uu + 2 * ww == 17 * ex + 26 * ey + 35 * ez\n",
    "        @test 7 * uu - 2 * ww == -3 * ex + 2 * ey + 7 * ez\n",
    "        @test 3 * uu + 2 * vv + ww == 16 * ex + 22 * ey + 28 * ez\n",
    "        @test (sympy.sqrt(2) * u + sympy.Rational(2, 3) * v) ⋅ ey == \n",
    "            sympy.sqrt(2) * (u ⋅ ey) + sympy.Rational(2, 3) * (v ⋅ ey)\n",
    "    end\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "using Profile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "Profile.init(n = 10^8, delay = 0.01)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      " 27.347987 seconds (7.76 M allocations: 377.404 MiB, 1.26% gc time)\n"
     ]
    }
   ],
   "source": [
    "@time @profile test_all(PGA3D)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": false
   },
   "outputs": [],
   "source": [
    "using ProfileView\n",
    "ProfileView.svgwrite(\"profile_results.svg\",combine = true, colorgc=false, pruned=[\n",
    "        (\"PyObject\", raw\"pyfncall.jl\"),\n",
    "        (\"_pycall!\", raw\"pyfncall.jl\")])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.1.0",
   "language": "julia",
   "name": "julia-1.1"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.1.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
